【发布时间】:2011-04-29 12:52:50
【问题描述】:
主干中是否有任何类型的钩子,我可以轻松地说“每当任何集合正在获取数据时,显示微调器,完成后将其隐藏”?
我感觉它会比这更复杂,并且需要覆盖特定的函数。我应该什么时候展示微调器?在fetch() 或refresh() 或其他什么地方?
【问题讨论】:
标签: javascript jquery backbone.js underscore.js
主干中是否有任何类型的钩子,我可以轻松地说“每当任何集合正在获取数据时,显示微调器,完成后将其隐藏”?
我感觉它会比这更复杂,并且需要覆盖特定的函数。我应该什么时候展示微调器?在fetch() 或refresh() 或其他什么地方?
【问题讨论】:
标签: javascript jquery backbone.js underscore.js
您可以使用 jQuery ajaxStart 和 ajaxStop。这些将在发出 ajax 请求时全局运行,因此 fetch 和 save 将导致它们运行。添加代码以在开头显示微调器并在最后隐藏它。
【讨论】:
在 Backbone.js 1.0.0 中,您可以使用 request 和 sync 事件 http://backbonejs.org/#Events-catalog
这在视图中。
initialize: function(){
this.items = new APP.Collections.itemCollection();
this.items.bind('request', this.ajaxStart, this);
this.items.bind('sync', this.ajaxComplete, this);
}
ajaxStart: function(arg1,arg2,arg3){
//start spinner
$('#item-loading').fadeIn({duration:100});
},
ajaxComplete: function(){
$('#item-loading').fadeOut({duration:100});
}
这可以为每个集合或每个模型应用这里是微调器的一些 CSS http://abandon.ie/notebook/simple-loading-spinner-for-backbonejs
【讨论】:
当Collection::fetch() 启动 (see source code) 时,Backbone 不会触发任何事件,因此您必须重写 fetch 方法。也许是这样的:
var oldCollectionFetch = Backbone.Collection.prototype.fetch;
Backbone.Collection.prototype.fetch = function(options) {
this.trigger("fetch:started");
oldCollectionFetch.call(this, options);
}
这将覆盖fetch 方法,以便在获取开始时为您提供一个事件。但是,这只会触发特定集合实例上的事件,因此如果您有一堆不同的集合,则必须在每个集合上监听该事件。
【讨论】:
我在不覆盖主干的情况下这样做的方法是:
在视图中
var myView = Backbone.View.extend({
initialize; function(){
this.$el.addClass('loading');
collection.fetch(success:function(){
this.$el.removeClass('loading')
})
}
})
另一种方法是在添加模型时删除加载类,通常你有:
var myView = Backbone.View.extend({
initialize; function(){
_.bindAll(this, 'addAll')
collection.bind('reset', this.addAll)
this.$el.addClass('loading');
collection.fetch();
},
addAll: function(){
this.$el.removeClass('loading');
collection.each(this.addOne);
}
})
这些在大多数情况下几乎是相同的,因为加载器确实是为了用户体验,在显示内容之前删除它是有意义的。
【讨论】:
还有一点更新。自 2012 年 12 月 13 日起,已向 Backbone.sync 添加了一个 "request" 事件,该事件在开始向服务器发出请求时触发。自 2012 年 1 月 30 日起,我们还添加了一个 "sync" 事件,该事件会在模型状态与服务器成功同步(创建、保存、销毁)时触发。
因此,您不需要覆盖或扩展本机 Backbone 的方法。对于侦听“开始/完成获取”事件,您可以将侦听器添加到您的模型/集合中,例如:
var view = new Backbone.View.extend({
initialize: function() {
this.listenTo(this.model, 'request', this.yourCallback); //start fetching
this.listenTo(this.model, 'sync', this.yourCallback); //finish fetching
}
});
【讨论】:
您可以在任何模型上创建一个名为 sync 的方法,backbone.js 将调用该方法以进行同步。或者您可以简单地替换方法Backbone.sync. 这将允许您只在源代码中的一处进行更改。
【讨论】:
我在我的主干中使用了NProgress,它是目前功能最好的加载器/微调器。
var view = Backbone.View.extend({
initialize: function () {
this.items = new APP.Collections.itemCollection();
this.items.on('reset', this.myAddFunction, this);
NProgress.start();
collection.fetch({
reset:true,
success: function () {
NProgress.done(true);
}
});
}
});
【讨论】:
使用 Backbone 同步方法, 它会调用每次主干同步方法,不仅获取,保存,更新和删除也
/* 除了直接 ajax 之外,每个请求都会覆盖同步应用程序 */
Backbone._sync = Backbone.sync;
Backbone.sync = function(method, model, options) {
// Clone the all options
var params = _.clone(options);
params.success = function(model) {
// Write code to hide the loading symbol
//$("#loading").hide();
if (options.success)
options.success(model);
};
params.failure = function(model) {
// Write code to hide the loading symbol
//$("#loading").hide();
if (options.failure)
options.failure(model);
};
params.error = function(xhr, errText) {
// Write code to hide the loading symbol
//$("#loading").hide();
if (options.error)
options.error(xhr, errText);
};
// Write code to show the loading symbol
//$("#loading").show();
Backbone._sync(method, model, params);
};
【讨论】: