这里对Backbone很新。我试图重新创建ToDo示例,而不复制和粘贴我遇到的教程中的代码。我也使用Parse.com作为我的后端。我坚持尝试使用Backbone View使用待办事项填充我的收藏。这是我的观点...
app.ItemsView = Backbone.View.extend({
tagName: "section",
initialize: function() {
app.items = new app.ItemCollection;
app.items.query = new Parse.Query(app.Item);
app.items.fetch();
console.log(app.items.models.length);
var itemsInJSON = [];
app.items.models.forEach(function(item){
console.log("Item being pushed is " + item);
itemsInJSON.push(item.toJSON());
});
this.render(app.items);
},
render: function(items) {
items.each(this.addItem, this);
return this;
// $("#bucketList").html(itemsView.render().el);
},
addItem: function(item) {
var itemView = new app.ItemView ({model: item});
this.$el.append(itemView.render().el)
}
});
我已经在Parse.com上查看了我的应用程序,我可以看到我的数据库中保存了2个项目。我知道存在问题,因为当我在初始化时调用console.log(app.items.models.length);
时,我的长度为0.但是当我在页面加载后直接在Chrome开发工具控制台中键入app.items.models.length
时,我得到了一个长度为2。
为什么我的初始化没有提取项目来填充我的收藏?
答案 0 :(得分:0)
由于fetch
实际上是在执行AJAX请求,因此它是异步的,您必须处理这个事实。它会返回一个jqXHR对象,如docs中所述,因此您的代码应该执行类似的操作
app.items.fetch().then(function() {
console.log(app.items.models.length);
...
this.render();
}.bind(this));
这确保了依赖于AJAX请求结果的代码仅在该请求完成后才会执行。
请注意,我使用.bind(this)
来确保在jqXHR承诺的回调中我可以以this
的形式访问该视图。这仅适用于IE9 +(请参阅MDN),如果您需要支持IE8或更低版本,请使用下划线_.bind。
答案 1 :(得分:0)
在这种情况下,我建议你不要在承诺中使用Jquery。 在这种情况下,Backbone使用事件来管理/帮助。
你应该做的第一件事是将模型/集合逻辑(fetch,set,get等)移到模型/集合中
然后你可以在你的视图中找到这样的东西:
this.lintenTo(app.items, "sync", this.render);
这是处理这些情况的主要方式。
但为什么不使用Promises?
当你在视图中执行fetch()时,你已经打破了SRP,因为如果由于某种原因将来你需要改变调用fetch的方式,你需要触摸视图文件,但请记住,fetch是一个模型/集合函数,在我看来,这意味着视图有多个改变的原因。此外,当您在视图中执行fetch()并使用promises时,您需要使用bind(this)来保留范围,在我看来,您可以避免它只是将此代码传递给模型/集合并只是在视图中侦听事件。 对于任何模型/集合函数(获取,保存,销毁,设置,获取......)都是一样的。