Javascript 主干JS视图渲染未显示
在下面的代码中,无法呈现“TodoList”。似乎抓取需要时间,因此显示“Javascript 主干JS视图渲染未显示,javascript,jquery,backbone.js,Javascript,Jquery,Backbone.js,在下面的代码中,无法呈现“TodoList”。似乎抓取需要时间,因此显示“0”和仅在之前 我也不知道为什么后来会显示“3”和“Descriptions”。我只需要在页面中显示“说明列表””。我能够从服务器上获取数据,但不知何故,无法在数据到达时立即显示。请告诉我在下面的代码中需要做什么更改 <html> <head> <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/tw
0
”和代码>仅在之前
我也不知道为什么后来会显示“3
”和“Descriptions
”。我只需要在页面中显示“说明列表”
”。我能够从服务器上获取数据,但不知何故,无法在数据到达时立即显示。请告诉我在下面的代码中需要做什么更改
<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>
var TodoItem=Backbone.Model.extend({
urlRoot:'api',
})
var TodoCollection=Backbone.Collection.extend({
型号:TodoItem,
url:'api/todos'
})
var TodoView=Backbone.View.extend({
模板:u.模板(“”+“”+“”),
render:function(){
this.$el.html(this.template(this.model.toJSON()))
}
})
var TodoListView=Backbone.View.extend({
初始化:函数(){
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:函数(todoItem){
console.log(todoItem.get('description'))
var todoView=new todoView({model:todoItem})
此.el.append(todoView.render())
}
})
var todoItem=new todoItem()
var todoList=new TodoCollection()
var todoListView=newtodolistView({el:'#demo',collection:todoList})
todoListView.render()文件
console.log(todoListView.el)
这是我得到的控制台输出:
0
<div id="demo"></div>
3
pick up cookies
Milk
Cookies
0
3.
捡饼干
牛奶
曲奇饼
对于初学者,您可能希望从获取中取出{reset:true}。
无论如何,获取将自动清除模型/集合
请在命令末尾使用分号,不使用分号会让浏览器解释分号的位置。这需要时间并且容易出错(浏览器可能只是将其放置在您认为不会的位置)
如果这不起作用,您可能希望执行以下操作,将提取添加到渲染中:
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);
},
我不知道为什么“3”和“Descriptions”后来才显示出来,因为它是异步Ajax请求的结果
现在,尝试更改代码(查看注释):
var TodoView=Backbone.View.extend({
模板:u.模板(“”+“”+“”),
clearItem:function(){
此.$el.find(“h3”).remove();
},
render:function(){
//视图中的所有DOM操作
this.el.append(this.template(this.model.attributes));
归还这个;
}
})
var TodoListView=Backbone.View.extend({
初始化:函数(){
//拆分“重置”事件和“添加”事件
this.listenTo(this.collection,'reset',this.removeAll);
this.listenTo(this.collection,'add',this.addOne);
this.collection.fetch({reset:true});
},
removeAll:function(){
//方法从视图中删除所有元素
//您的问题是,此事件将在ajax请求完成之前触发
日志(“重置!”);
var todoView=new todoView();
todoView.clearItem();
},
addOne:函数(todoItem){
//当集合中的模型更改(获取结果后自动)每个模型时激发。
日志(“添加项:”,todoItem);
var todoView=new todoView({model:todoItem})
todoView.render();
}
});
注意:删除代码中的todoListView.render()
对不起,我的英语太差了。我没有时间更好地解释。试试我的代码是否有效
- 主干网中的活动:
- 获取集合:
- 渲染视图:
您能添加一个可尝试的示例吗?我不确定为什么稍后会显示“3”和“说明”
——因为这是异步Ajax请求的结果。尝试更改此:this.$el.html(this.template(this.model.toJSON())
与this.$el.html(this.template(this.model.attributes))
@Frogmouth仍然相同的结果我会收到更多的答复,请……让我们知道这是否是您的正确答案;)您好,我刚刚尝试了上面的代码,我得到的错误是:uncaughttypeerror:cannotread undefinedhey@user3815806的属性'length',我忘了将此传递给函数。请用上面的脚本再试一次!需要使用reset:true
来获取fetch
以触发'reset'
事件,从而触发初始render
调用。调用fetch
insiderender
对我来说似乎有点奇怪,调用this.collection.fetch().done(this.render.bind(this))
insideinitialize
?我不会说它奇怪,这取决于您设置视图的方式。在上面的例子中,他在代码中单独调用渲染。在我看来,这是一个很好的实践,因为你只在需要的时候才渲染。在渲染工作中运行fetch。虽然它确实有点“无结构”。在大多数情况下,您可能会在设置视图后立即运行“渲染”。因此,从初始化中调用渲染是一种很好的做法,也许是最好的做法。不知道,但这可能也会起作用:var todoListView=newtodolistView({el:'#demo',collection:todoList}).done(this.render);
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();
}
});