当多个视图共享相同模型时,在骨干视图呈现期间单个服务器调用

时间:2017-01-04 11:55:18

标签: javascript backbone.js backbone-views backbone-events backbone-model

我有一个视图的多个实例,它们之间共享模型的单个实例。

在渲染视图期间,我想在模型中调用一个函数,该函数使服务器调用仅获取一些数据。

由于这些视图是相同视图的实例,因此它们都在触发模型内部的功能。因此进行多个服务器调用 不知道我怎么能只在模型内触发一次这个函数。

2 个答案:

答案 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