我有一个视图的多个实例,它们之间共享模型的单个实例。
在渲染视图期间,我想在模型中调用一个函数,该函数使服务器调用仅获取一些数据。
由于这些视图是相同视图的实例,因此它们都在触发模型内部的功能。因此进行多个服务器调用 不知道我怎么能只在模型内触发一次这个函数。
答案 0 :(得分:1)
假设您在模型上调用fetch
。此调用将返回请求(实际上是jqXHR对象)。所以一个非常有用的模式是:
fetchOnce: function() {
if (!this.fetchRequest || this.fetchRequest.readyState == 4 && this.fetchRequest.status >= 400) {
this.fetchRequest = this.fetch.apply(this, arguments);
}
return this.fetchRequest;
},
这将在调用fetch时保存请求,并在当前请求正在进行或成功完成时避免任何其他调用。
因为jqXHR对象是Deferred Promise对象,所以只要调用fetchOnce
,就可以随时添加回调(如deferred.done):
model.fetchOnce().done(function() { console.log('model fetched!'); });
答案 1 :(得分:0)
扩展mikeapr4's answer,我创建了一个简单的模型,它覆盖.sql
函数只能获取一次(可选每X小时)。
它使用jQuery的延迟.state()
function来确定请求是待处理还是已完成。
请注意,我使用MomentJS来计算时差,但可以使用JavaScript本机日期轻松实现。
fetch
然后它对视图是透明的,它可以随意调用var FetchOnceModel = Backbone.Model.extend({
fetchDelay: 8, // hours before forcing another fetch,
/**
* False if the promise is pending, or the last fetch was within the delay.
* Force a new fetch if the lang has changed since the last fetch.
* @return {Boolean} fetch is needed
*/
isFetchDue: function() {
var lastFetch = this.lastFetch,
promise = this.promise,
// use the jQuery deferred `state` function
isPending = promise && promise.state() === "pending";
return !isPending && !lastFetch || // not fetched yet?
(this.fetchDelay && moment().diff(lastFetch, 'hours') > this.fetchDelay); // is delay passed?
},
fetch: function() {
if (this.isFetchDue()) {
this.promise = this.fetch({
context: this,
success: this._onSync,
error: this._onError
});
}
return this.promise;
},
_onSync: function() {
this.lastFetch = moment();
this.onSync.apply(this, arguments);
},
_onError: function() {
this.lastFetch = null;
this.onError.apply(this, arguments);
},
// left to override by the child model
onError: _.noop,
onSync: _.noop
});
。
使用它的简单视图:
fetch