web-dev-qa-db-ja.com

Backbone.js:モデルのコレクションをフェッチしてレンダリングします

Backbone.jsを使用してJavaScriptMVCアプリケーション開発を学習していて、ビューでのモデルコレクションのレンダリングに問題があります。これが私がやりたいことです:

  • ページの読み込みが完了すると、モデルコレクションとしてサーバーからデータを取得します

  • ビューでそれらをレンダリングします

それが私がやりたいことのすべてであり、これが私がこれまでに持っているものです:

$(function(){

    "use strict";

    var PostModel = Backbone.Model.extend({});

    var PostCollection = Backbone.Collection.extend({
        model: PostModel,
        url: 'post_action.php'
    });

    var PostView = Backbone.View.extend({
        el: "#posts-editor",        

        initialize: function(){
            this.template = _.template($("#ptpl").html());
            this.collection.fetch({data:{fetch:true, type:"post", page:1}});
            this.collection.bind('reset', this.render, this);
        },

        render: function(){
            var renderedContent = this.collection.toJSON();
            console.log(renderedContent);
            $(this.el).html(renderedContent);
            return this;
        }
    });

    var postList = new PostCollection();
    postList.reset();
    var postView = new PostView({
        collection: postList
    });

});

問題

私の知る限り、Chromeはサーバーからの応答をログに記録しており、希望どおりにJSON形式になっています。しかし、ビューには表示されません。コンソールに明らかなエラーはありません。 。

サーバーには、GETパラメーターを受け入れ、JSONをエコーするハンドラーがあります。http://localhost/blog/post_action.php?fetch=true&type=post&page=1

[
   {
      "username":"admin",
      "id":"2",
      "title":"Second",
      "commentable":"0",
      "body":"This is the second post."
   },
   {
      "username":"admin",
      "id":"1",
      "title":"Welcome!",
      "commentable":"1",
      "body":"Hello there! welcome to my blog."
   }
]
15
hyde

コードには2つの潜在的な問題があります。

  1. イベントリスナーのコールバックは、collection.fetch()を呼び出す前に登録する必要があります。そうしないと、リスナーが登録される前にトリガーされる可能性があるため、最初のresetイベントを見逃す可能性があります。

  2. resetイベントは、コレクションが更新されるたびにビューが再レンダリングされることを保証するのに十分ではありません。

また、object.listenTo()フォームを使用してイベントをバインドすることをお勧めします。これにより、ビューが閉じられたときに適切な登録解除が保証されます。そうしないと、 バックボーンゾンビ として知られているものになってしまう可能性があります。これが解決策です。

this.listenTo( this.collection, 'reset add change remove', this.render, this );
this.collection.fetch({ data: { fetch:true, type:"post", page:1 } });

同じオブジェクトから複数のイベントを空白で区切って登録する方法に注意してください。

10
mor

変化する

this.collection.bind('reset', this.render, this);

this.collection.bind('sync', this.render, this);

問題は、最初に一度だけリセットを実行することです。その時点では、レンダリングするものは何もありません。次回、コレクションをフェッチするときに、オプション{reset:true}なしでコレクションをフェッチするため、resetイベントは発生しません。

2
Artem Volkhin

この行を変更します

this.collection.bind('reset', this.render, this);

this.listenTo(this.collection, 'reset', this.render);
1
Sushanth --

コレクションをフェッチするときに、リセットイベントはデフォルトでは発生しなくなりました。 (バージョン1.0以降)コレクションがフェッチされたときにBackboneでリセットイベントを発生させるには、次のようにfetchメソッドを呼び出す必要があります。

this.collection.fetch({reset: true});
0
Rogier