4

_bind.Allバインディングとbackbone.jsの目的について混乱しています。#modal以下は、モーダルビューを作成し、バックエンドからフェッチされたコメントをレンダリングする作業コードです。

まず、以下のコードでは、initialize関数にあります_.bindAll(this, 'render', 'renderComments');。私がするかどうかにかかわらず_.bindAll()、私は電話this.render()this.renderComments()内部に問題はありませんinitialize()。いつ助けになるのか、いつ役に立たないのかという例はあり_.bindAll()ますか?

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.commentList = new CommentCollection();
        var self = this;
        this.commentList.fetch({
            data: { post_id: this.model.id},
            processData: true,
            success: function() {
                self.commentListView = new CommentListView({ collection: self.commentList });
            }
        });
    }
});

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

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

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

第二に、私は何かの前に置くことについて混乱this.しています。たとえば、でrenderComments、なぜ私は使用できないのですか?

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

行の場合、クラスをthis.commentList = new CommentCollection();インスタンス化する以外に、の子になりますか?CommentCollection()commentListModalView

さらに、コールバック関数で後でvar self = this;使用する必要がありますか?self.commentListViewバインディングを使用してアクセスできるようにすることはできますthis.commentListViewか、それともvar self = this従来の方法を使用していますか?

最後にself.commentListView = new CommentListView({ collection: self.commentList });、success関数では、代わりにのinitializeメソッドにrenderComments移動し、バインドして、あまりにも多くの関数をネストしないようにする必要がありますか?これにより、次のようになります。CommentListViewthis.collection.on('reset');

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.commentList = new CommentCollection();
        this.commentListView = new CommentListView({ collection: this.commentList });
        this.commentList.fetch({
            data: { post_id: this.model.id},
            processData: true
        });
    }
});

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

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

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

1 に答える 1

8

おい-長い質問;)

1)_.bindAll最初にバックボーンを使用していたときは、初期化メソッドで行っていましたが、その後停止しました。イベントにバインドしている場合を除いて、通常は必要ありません。そうすれば、非常に役立ちます。たとえば、次の場合:

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

_.bindAll(this, 'clickHandler')そうしないと、ポインタthisがビューになりません。

2)私があなたの質問を理解した場合:commentListのインスタンスのプロパティになりますModalView

3)使用var self = this;は比較的一般的ですが、多くの場合、Underscore.js(backbone.jsの依存関係)のオーバーロードのために回避できます。たとえば、ほとんどの収集関数(map、、eachなど)は、最後のパラメーターとしてコンテキストを取ります。だから代わりに

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

できるよ:

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

あなたの場合、あなたはあなたのsuccess方法を次のように置き換えることができます

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

このポインターのやや紛らわしい主題についてさらに情報が必要な場合は、次の優れたチュートリアルをお勧めします:http: //bonsaiden.github.com/JavaScript-Garden/#function.this

4)はい-レンダリングをに移動しますreset。そうすれば、他の何かがコレクションのリセットを引き起こした場合、ビューはそれを取得します。

私があなたのすべての質問に答えたことを望みます。

于 2012-07-09T21:29:46.710 に答える