使用Backbone.js,我有一个我实例化的集合,X
。实例化后,我立即调用X.fetch()
,以便尽快从服务器加载数据。然后,我将X
传递给将对集合进行操作的各种视图。
这些视图的最佳方法是区分何时集合只是加载(因此为空)以及何时加载但实际上是空的?我想我的观点显示适当的“加载...”文本,直到该集合已经ping通服务器。在这一点上,我希望他们说“看起来这里什么都没有。也许你应该添加一些东西。”
我在考虑在每个视图中收听集合上的reset
事件,但这对我来说似乎相当脆弱。如果在视图附加其侦听器之前已经触发重置事件,会发生什么?是否有一个很好的模式来检查集合的状态,以确定它是否被取出?
答案 0 :(得分:3)
fetch
方法基于AJAX的异步性质是异步的。
因此,您需要实现事件驱动的行为。
X.fetch({
success: function(collection, response) {
hidePreLoader();
renderViews(collection); // collection argument is your X collection.
}
});
<强>更新强>
根据您对我的回答的评论,我可以提出另一个想法。 即你可以设置
X.isLoaded = true;
或任何其他属性,如
X.loadedAt = Date.now();
在success
回调中,因此其他代码可以检查此属性的状态。
但是我在这里看到了一种糟糕的设计。
您可以使用preloader显示您的视图,并在success
回调触发器中,您的视图将开始与集合一起使用,因为它已加载并准备使用。
总的来说,我再次建议你使用事件驱动的行为。
我没有测试,但这是我的想法的代表:
var XCollection = Backbone.Collection.extend({
// ...
model: X,
loadState: {},
loadedAt: -1,
initialize: function(options) {
_.extend(this.loadState, Backbone.Events);
},
isLoaded: function() {
return this.loadedAt > -1;
}
});
var Subview = Backbone.View.extend({
// ...
initialize: function(options) {
this.collection.loadState.on("loadComplete",
this.onLoadComplete, this);
},
onLoadComplete: function(response) {
this.hidePreloader();
this.renderData();
},
/**
* Checks is the collection loaded and view can render fetched models.
* It's just an example.
* You'll not need to use it if you're handling a loadComplete event.
*/
isRenderingAllowed: function() {
return this.collection.isLoaded();
}
});
var XView = Subview.extend({
// ...
initialize: function(options) {
Subview.prototype.initialize.apply(this, arguments);
}
});
var YView = Subview.extend({
// ...
initialize: function(options) {
Subview.prototype.initialize.apply(this, arguments);
}
});
// ...
var x = new XCollection();
var xView = new XView({collection: x}),
yView = new YView({collection: x});
x.fetch({
success: function(collection, response) {
collection.loadedAt = Date.now();
collection.loadState.trigger("loadComplete", response);
}
});
答案 1 :(得分:1)
确保在致电fetch()
之前初始化视图。这样您就可以监听reset
事件,并确保所有视图都已更新。如果你想尽快加载xlist,最好将它引导到你的html服务器端。
这样做的方法可能是:
<script src="/public/js/collecions/x-list.js">
<script src="/public/js/views/x-view.js">
<script>
var xlist = new App.Collections.XList();
_.each($(".xdiv"), function(el){
new App.Views.XView({
el: el,
collection: xlist
});
// make sure that XView have this in it's initialize method:
// this.collection.bind("reset", this.render, this)
}
xlist.fetch();
// or even better, use bootstraped data:
x.list.reset((<%= @data.to_json %>)
</script>