我的todos.js:
var app = app || {};
(function () {
'use strict';
var Todos = Backbone.Collection.extend({
model: app.Todo,
url: '/api/todos'
});
app.todos = new Todos();
})();
APP-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.
更新
我尝试了以下代码。但没有'好的'或者'错误'登录控制台。
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 :(得分:1)
fetch
是异步的,所以当你立即渲染后,集合仍然是空的。
根据定义,任何需要调用服务器的函数都是异步的。在不锁定浏览器的情况下,它们无法同步。
使用Backbone提供的回调轻松解决此问题:
initialize: function() {
/** ...snip... */
app.todos.fetch({
reset: true,
context: this,
success: this.render
});
},
此外,如果从API收到的数据采用以下格式:
{
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>
&#13;
答案 1 :(得分:1)
这是因为所有提取都是异步的。所以你的渲染在它取出你的待办事项之前就已经开始了。
完成提取后,您可以重新渲染:
app.todos.fetch().done(function(){
self.render();
});
您还可以收听模型的同步事件:
this.listenTo(app.todos, 'sync', this.render);