2016-11-01 9 views
-1

マイtodos.js:コレクションの長さが0だがフェッチが成功した理由は?

var app = app || {}; 

(function() { 
    'use strict'; 
    var Todos = Backbone.Collection.extend({ 
     model: app.Todo, 
     url: '/api/todos' 
    }); 
    app.todos = new Todos(); 
})(); 

アプリ-view.js

var app = app || {}; 
(function($){ 
    'use strict'; 
    app.AppView = Backbone.View.extend({ 
     el: '.todoapp', 
     events : { 
      'keypress .new-todo': 'createOnEnter' 

     }, 

     initialize: function() { 
      this.$input = this.$('.new-todo'); 
      this.$list = $('.todo-list'); 
      app.todos.fetch({ 
       reset : true 
      }); 
      this.render(); 
     }, 


     render: function(){ 
      console.log(' len = ' + app.todos.length); 
      app.todos.each(function(todo){ 
       this.renderTodo(todo); 
      }, this); 
     }, 
... 

フェッチされたデータ

[{ 
    "_id": "5801", 
    "title": "testtitle123", 
    "completed": false, 
    "__v": 0 
}, { 
    "_id": "58182", 
    "title": "testtitle126", 
    "completed": false, 
    "__v": 0 
}, { 
    "_id": "5813", 
    "title": "testtitle127", 
    "completed": false, 
    "__v": 0 
}] 

それは(http://myip:8000/api/todosから)データをフェッチすることに成功しました。しかしコンソールから、長さは、私は以下のコードを試してみました常に0

UPDATE

です。コンソールに「OK」または「エラー」は記録されません。

var app = app || {}; 
    (function($){ 
     'use strict'; 
     app.AppView = Backbone.View.extend({ 
      el: '.todoapp', 
      events : { 
       'keypress .new-todo': 'createOnEnter' 

      }, 

      initialize: function() { 
       this.$input = this.$('.new-todo'); 
       this.$list = $('.todo-list'); 
       this.listenTo(app.todos, 'sync', this.render); 
       app.todos.fetch({ 
        reset : true, 
        context: this, 
        success: function(col, res, op) { 
         console.log('OK'); 
        }, 
        error: function(col, res, op){ 
         console.log('error'); 
        } 
       }); 
      }, 

      render: function(){ 
       console.log(' len = ' + app.todos.length); 
       app.todos.each(function(todo){ 
        this.renderTodo(todo); 
       }, this); 
      }, 

      renderTodo: function(todo) { 
       console.log('render :' + todo.title); 
       var todoView = new app.TodoView({ model : todo }); 
       this.$list.append(todoView.render().el); 
      }, 
     }); 

    })(jQuery); 
+0

受信したデータは何ですか? –

+0

答えに無関係で混乱しやすいので、あなたの質問への回答からコードを編集しないでください。 –

+0

その時点でもう一方のコードが機能するはずですので、調査する必要があります。 'render'はどこか他のところから呼び出されているのでしょうか? –

答えて

1

fetchは非同期なので、すぐにレンダリングすると、コレクションはまだ空です。

サーバーを呼び出す必要がある関数はすべて、定義によって非同期です。ブラウザをロックしないと同期できません。

簡単にこれを解決するためのバックボーンが提供するコールバックを使用してください:データがAPIから受信した場合、また

initialize: function() { 
    /** ...snip... */ 
    app.todos.fetch({ 
     reset: true, 
     context: this, 
     success: this.render 
    }); 
}, 

は形式である:

{ 
    data: [ 
     {...}, 
     {...} 
    ] 
} 

あなたはparse機能を提供する必要がありますあなたのコレクション:

var Todos = Backbone.Collection.extend({ 
    model: app.Todo, 
    url: '/api/todos', 
    parse: function(response) { 
     return response.data; 
    } 
}); 

var PostCollection = Backbone.Collection.extend({ 
 
    url: 'https://jsonplaceholder.typicode.com/posts', 
 
}); 
 

 

 
var collection = new PostCollection(); 
 
collection.fetch({ 
 
    reset: true, 
 
    context: this, 
 
    success: function() { 
 
    console.log("Success:", collection.length); 
 
    } 
 
}); 
 

 
Simplest demo of fetching and checking the `length`.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone-min.js"></script>

+0

試しました。うまくいきません。 – BAE

1

すべてのフェッチが非同期であるためです。だからあなたのレンダリングはあなたのtodosをフェッチする前に実行されています。

行われるフェッチ一度あなたが再描画できます。

app.todos.fetch().done(function(){ 
    self.render(); 
}); 

はまた、あなたのモデルの同期イベントに耳を傾けることができます:

this.listenTo(app.todos, 'sync', this.render); 

http://backbonejs.org/#Sync

+0

ここではjQuery promise APIを使用する必要はありません。 –

+1

@ n00btronはエラーを修正しました。これは、jsファイルをインポートする順序が間違っていたためです。申し訳ありません。 – BAE

関連する問題