最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Binding and _.bindAll in backbone.js - Stack Overflow

programmeradmin2浏览0评论

I am confused about binding and the purpose of _bind.All in backbone.js. Below is a working code that creates a Modal view #modal and renders out ments fetched from the backend.

Firstly, in the code below, I have in the initialize function _.bindAll(this, 'render', 'renderComments');. Whether or not I do _.bindAll(), I have no problems calling this.render() and this.renderComments() inside initialize(). Are there any examples of when _.bindAll() will help us and when it will not?

ModalView = Backbone.View.extend({
    el: $('#modal'),

    template: _.template( $('#tpl_modal').html() ),

    initialize: function() {
        _.bindAll(this, 'render', 'renderComments');
        this.render();
        this.renderComments();
    },

    render: function() {
        $(this.el).fadeIn('fast').append( this.template( this.model.toJSON( this.model ) ) );
    },

    renderComments: function() {
        thismentList = new CommentCollection();
        var self = this;
        thismentList.fetch({
            data: { post_id: this.model.id},
            processData: true,
            success: function() {
                selfmentListView = new CommentListView({ collection: selfmentList });
            }
        });
    }
});

And

CommentListView = Backbone.View.extend({
    el: '.modal_ments',

    initialize: function() {
        this.render();
    },

    render: function() {
        var self = this;
        this.collection.each( function(ment, index) {
            $(self.el).append( new CommentListItemView({ model: ment }).render().el );
        });
        return this;
    }
});

Secondly, I am confused about prepending this. to something. For example in renderComments, why cant I use:

var mentList = new CommentCollection();
var self = this;
mentList.fetch({.... });

For the line thismentList = new CommentCollection();, other than instantiating the class CommentCollection(), does it make mentList a child of ModalView?

Additionally, is it necessary to have var self = this; and use selfmentListView later in the callback function? Can binding be used so I can access thismentListView, or is using var self = this the conventional way of doing things?

Finally, should selfmentListView = new CommentListView({ collection: selfmentList }); in the success function of renderComments be moved to CommentListView's initialize method instead and be binded to this.collection.on('reset'); to prevent nesting too many functions? This will result in:

ModalView = Backbone.View.extend({
    el: $('#modal'),

    template: _.template( $('#tpl_modal').html() ),

    initialize: function() {
        _.bindAll(this, 'render', 'renderComments');
        this.render();
        this.renderComments();
    },

    render: function() {
        $(this.el).fadeIn('fast').append( this.template( this.model.toJSON( this.model ) ) );
    },

    renderComments: function() {
        thismentList = new CommentCollection();
        thismentListView = new CommentListView({ collection: thismentList });
        thismentList.fetch({
            data: { post_id: this.model.id},
            processData: true
        });
    }
});

CommentListView = Backbone.View.extend({
    el: '.modal_ments',

    initialize: function() {
        this.collection.on('reset', this.render, this);
    },

    render: function() {
        var self = this;
        this.collection.each( function(ment, index) {
            $(self.el).append( new CommentListItemView({ model: ment }).render().el );
        });
        return this;
    }
});

I am confused about binding and the purpose of _bind.All in backbone.js. Below is a working code that creates a Modal view #modal and renders out ments fetched from the backend.

Firstly, in the code below, I have in the initialize function _.bindAll(this, 'render', 'renderComments');. Whether or not I do _.bindAll(), I have no problems calling this.render() and this.renderComments() inside initialize(). Are there any examples of when _.bindAll() will help us and when it will not?

ModalView = Backbone.View.extend({
    el: $('#modal'),

    template: _.template( $('#tpl_modal').html() ),

    initialize: function() {
        _.bindAll(this, 'render', 'renderComments');
        this.render();
        this.renderComments();
    },

    render: function() {
        $(this.el).fadeIn('fast').append( this.template( this.model.toJSON( this.model ) ) );
    },

    renderComments: function() {
        this.mentList = new CommentCollection();
        var self = this;
        this.mentList.fetch({
            data: { post_id: this.model.id},
            processData: true,
            success: function() {
                self.mentListView = new CommentListView({ collection: self.mentList });
            }
        });
    }
});

And

CommentListView = Backbone.View.extend({
    el: '.modal_ments',

    initialize: function() {
        this.render();
    },

    render: function() {
        var self = this;
        this.collection.each( function(ment, index) {
            $(self.el).append( new CommentListItemView({ model: ment }).render().el );
        });
        return this;
    }
});

Secondly, I am confused about prepending this. to something. For example in renderComments, why cant I use:

var mentList = new CommentCollection();
var self = this;
mentList.fetch({.... });

For the line this.mentList = new CommentCollection();, other than instantiating the class CommentCollection(), does it make mentList a child of ModalView?

Additionally, is it necessary to have var self = this; and use self.mentListView later in the callback function? Can binding be used so I can access this.mentListView, or is using var self = this the conventional way of doing things?

Finally, should self.mentListView = new CommentListView({ collection: self.mentList }); in the success function of renderComments be moved to CommentListView's initialize method instead and be binded to this.collection.on('reset'); to prevent nesting too many functions? This will result in:

ModalView = Backbone.View.extend({
    el: $('#modal'),

    template: _.template( $('#tpl_modal').html() ),

    initialize: function() {
        _.bindAll(this, 'render', 'renderComments');
        this.render();
        this.renderComments();
    },

    render: function() {
        $(this.el).fadeIn('fast').append( this.template( this.model.toJSON( this.model ) ) );
    },

    renderComments: function() {
        this.mentList = new CommentCollection();
        this.mentListView = new CommentListView({ collection: this.mentList });
        this.mentList.fetch({
            data: { post_id: this.model.id},
            processData: true
        });
    }
});

CommentListView = Backbone.View.extend({
    el: '.modal_ments',

    initialize: function() {
        this.collection.on('reset', this.render, this);
    },

    render: function() {
        var self = this;
        this.collection.each( function(ment, index) {
            $(self.el).append( new CommentListItemView({ model: ment }).render().el );
        });
        return this;
    }
});
Share Improve this question edited Jul 9, 2012 at 20:58 Nyxynyx asked Jul 9, 2012 at 20:42 NyxynyxNyxynyx 63.9k163 gold badges507 silver badges856 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

phew--long question(s) ;)

1) I used to do _.bindAll in my initialize methods when I was first using backbone but I have since stopped. It's not normally needed unless you're binding to events and then it's really helpful. For example if you have:

events:
{
    'click': clickHandler
},
clickHandler: function(){
    //do cool stuff
}

then it's helpful to do _.bindAll(this, 'clickHandler') otherwise your this pointer won't be the view

2) If i understand your question: mentList bees a property of your instance of ModalView.

3) using var self = this; is relatively mon, but in many cases can be avoided because of overloads in Underscore.js (which is a dependency of backbone.js). For instance, most of the collection functions (map, each, etc) take a context as the last parameter. so instead of

var self = this;
_.map([1,2], function(item){
    self.sum = self.sum + item; 
});

you can do:

_.map([1,2], function(item){
    this.sum = this.sum + item; 
}, this);

if your case you could replace your success method with

success: _.bind(function() {
             this.mentListView = new CommentListView({ collection: this.mentList });
         }, this);

If you want more info on the somewhat confusing subject of this pointers, it's suggest the following excellent tutorial: http://bonsaiden.github./JavaScript-Garden/#function.this

4) Yes--I would move the rendering to the reset. that way if something else causes a reset of the collection the view will pick it up.

Hope I answered all your questions.

发布评论

评论列表(0)

  1. 暂无评论