1

Backbone.js コードの例を見つけて、それを自分のニーズに合わせて採用しました。

render関数はCommentListView、コンテンツがフェッチされる前に呼び出されます。レンダリングするコンテンツがある場合、再度呼び出されないようです。

バックエンドは 2 つの結果を返すので、それは問題ではありません。

// Models
window.Comment = Backbone.Model.extend();

window.CommentCollection = Backbone.Collection.extend({
    model:Comment,
    url:"/api/comments/cosmopolitan"
});


// Views
window.CommentListView = Backbone.View.extend({

    tagName:'ul',

    initialize:function () {
        this.model.bind("reset", this.render, this);
    },

    render:function (eventName) {
        console.log(this.model.models);
        _.each(this.model.models, function (comment) {
            console.log(comment);
            $(this.el).append(new CommentListItemView({model:comment}).render().el);
        }, this);
        return this;
    }

});

window.CommentListItemView = Backbone.View.extend({

    tagName:"li",

    template:_.template($('#tpl-comment-list-item').html()),

    render:function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    }

});

// Router
var AppRouter = Backbone.Router.extend({

    routes:{
        "":"list"
    },

    list:function () {
        this.commentList = new CommentCollection();
        this.commentListView = new CommentListView({model:this.commentList});
        this.commentList.fetch();

        $('#sidebar').html(this.commentListView.render().el);
    }
});

var app = new AppRouter();
Backbone.history.start();
4

2 に答える 2

4

の動作はfetchBackbone 1.0.0 で少し変更されました。ChangeLogから:

  • Collection の "update" の名前をsetに変更しました。これは、類似の との並列処理と、resetmodel.set()との対比を目的としています。fetch後のデフォルトの更新メカニズムになりました。「リセット」を引き続き使用する場合は、 を渡します。{reset: true}

そして、次のCollection#fetchように述べています。

フェッチ collection.fetch([options])

このコレクションのデフォルトのモデル セットをサーバーから取得し、到着時にコレクションに設定します。[...] モデル データがサーバーから返されると、setを使用して (インテリジェントに) フェッチされたモデルをマージします{reset: true}

あなたinitializeだけにバインドし"reset"ます:

this.model.bind("reset", this.render, this);

"add"生成される、"remove"、および"change"イベントにバインドするか、Collection#set次の場合に明示的に"reset"イベントを要求できfetchます。

this.commentList.fetch({ reset: true });

私がここにいる間、他のいくつかのこと:

  1. CommentListViewビューはモデルではなくコレクションを使用しているため、次のように呼び出すことができますcollection

    this.commentListView = new CommentListView({collection: this.commentList});
    

    ビュー内を参照しthis.collectionます。View#initializeビュー コンストラクターが引数を処理する方法の詳細については、を参照してください。

  2. コレクションにはさまざまなUnderscore メソッドが混在しているため、this.collection.each(function(model) { ... })代わりに_.each(this.model.models, ...).
  3. ビューは、jQuery でラップされたキャッシュ バージョンを維持elする$elためthis.$el$(this.el).
  4. などに注意してくださいconsole.log(this.model.models)。コンソールは通常、ライブ参照を取得するため、コンソールに表示されるのは、呼び出されたthis.model.modelsときではなく、見たときの状態になりますconsole.logconsole.log(this.model.toJSON())タイミングと AJAX の問題に直面した場合は、使用する方が信頼性が高くなります。
  5. メモリ リークの影響を受けにくいため、 (AKA )listenToの代わりに切り替えたいと思うかもしれません。bindon
于 2013-08-24T17:48:43.143 に答える
0

通常、フェッチのリスナーを作成するために使用されます。フェッチが完了し、モデルまたはコレクションが変更されると、コールバックがあります。これを試して:

var AppRouter = Backbone.Router.extend({

    routes:{
        "":"list"
    },

    list:function () {
        this.commentList = new CommentCollection();
        this.commentListView = new CommentListView({model:this.commentList});
        this.listenTo(this.commentList,'change', this.makeRender);
        this.commentList.fetch();


    },
    makeRender: function(){
        $('#sidebar').html(this.commentListView.render().el);
   }

});
于 2013-08-24T15:23:44.637 に答える