在下面的代码中,无法呈现'TodoList'。似乎需要花费时间,因此仅在显示“0
”和<div id="demo"></div>
之前。
并且我不确定为什么'3
'和'Descriptions
'稍后会显示出来。我只需要在页面中显示“Descriptions List
”。我能够从服务器获取数据,但不知何故无法在数据到达时立即显示。请告诉我在下面的代码中需要做哪些更改?
<html>
<head>
<link rel="stylesheet"
href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.1/css/bootstrap.min.css">
</head>
<body>
<div id="demo"></div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
<script type="text/javascript">
var TodoItem = Backbone.Model.extend({
urlRoot: 'api',
})
var TodoCollection = Backbone.Collection.extend({
model: TodoItem,
url: 'api/todos'
})
var TodoView = Backbone.View.extend({
template: _.template('<h3> ' +'<input type=checkbox ' +'<% if(status === "complete") print("checked") %>/>' +' <%= description %></h3>'),
render: function(){
this.$el.html(this.template(this.model.toJSON()))
}
})
var TodoListView = Backbone.View.extend({
initialize: function(){
this.listenTo(this.collection,'reset',this.render)
this.collection.fetch({reset:true})
},
render: function(){
console.log(this.collection.length)
this.collection.forEach(this.addOne,this)
},
addOne: function(todoItem){
console.log(todoItem.get('description'))
var todoView = new TodoView({model: todoItem})
this.$el.append(todoView.render())
}
})
var todoItem = new TodoItem()
var todoList = new TodoCollection()
var todoListView = new TodoListView({el: '#demo', collection: todoList})
todoListView.render()
console.log(todoListView.el)
</script>
</body>
</html>
这是我获得的CONSOLE输出:
0
<div id="demo"></div>
3
pick up cookies
Milk
Cookies
答案 0 :(得分:1)
对于初学者,您可能希望从提取中取出{reset:true}。 无论如何,fetch会自动清除模型/集合。
请在命令末尾使用分号,不使用它们会让浏览器解释分号的位置。这需要时间并且容易出错(浏览器可能只是把它放在你认为不会的地方)。
如果这不起作用,您可能希望将fetch添加到渲染中,执行此操作:
render: function(){
var that = this;
this.collection.fetch().done(function(data) {
console.log(that.collection.length);
that.collection.forEach(that.addOne,that);
});
},
也可能有用,但你需要对此进行测试,我个人总是使用上面的那个:
render: function(){
this.collection.fetch().done(function(data) {
console.log(this.collection.length);
this.collection.forEach(this.addOne,this);
}, this);
},
答案 1 :(得分:0)
我不知道为什么&#39; 3&#39;和&#39;描述&#39;稍后显示 - 因为它是异步Ajax请求的结果。
现在,尝试更改您的代码(观看评论):
var TodoView = Backbone.View.extend({
template: _.template('<h3> ' +'<input type=checkbox ' +'<% if(status === "complete") print("checked") %>/>' +' <%= description %></h3>'),
clearItem : function(){
this.$el.find("h3").remove();
},
render: function(){
//all DOM manipulation in view
this.$el.append(this.template(this.model.attributes));
return this;
}
})
var TodoListView = Backbone.View.extend({
initialize: function(){
// split "reset" event and "add" event
this.listenTo(this.collection,'reset',this.removeAll);
this.listenTo(this.collection,'add',this.addOne);
this.collection.fetch({reset:true});
},
removeAll : function(){
//method to remove all element from view
//your problem is that this event will fire before ajax request done
console.log("reset!");
var todoView = new TodoView();
todoView.clearItem();
},
addOne: function(todoItem){
//fire when a model in the collection change (automatic after fetch result) for each model.
console.log("add ITEM:",todoItem);
var todoView = new TodoView({model: todoItem})
todoView.render();
}
});
注意:删除代码中的todoListView.render()
。
抱歉,我的英语太差了。我没有时间更好地解释。试试我的代码是否正常工作