我有一個視圖的多個實例,它們之間共享單個模型實例。當多個視圖共享相同模型時,骨幹視圖呈現期間的單個服務器調用
在渲染視圖的過程中,我想調用模型中的一個函數,使服務器調用一次只提取一些數據。
由於這些視圖是相同視圖的實例,它們都觸發模型內部的函數。因此進行多個服務器調用。
任何想法如何我只能在模型內部觸發此功能一次。
我有一個視圖的多個實例,它們之間共享單個模型實例。當多個視圖共享相同模型時,骨幹視圖呈現期間的單個服務器調用
在渲染視圖的過程中,我想調用模型中的一個函數,使服務器調用一次只提取一些數據。
由於這些視圖是相同視圖的實例,它們都觸發模型內部的函數。因此進行多個服務器調用。
任何想法如何我只能在模型內部觸發此功能一次。
假設您在模型上呼叫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;
},
這將節省請求被調用時,獲取並避免任何額外的呼叫,而當前的請求是正在進行的,或者如果它已成功完成。
由於jqXHR對象是Deferred Promise對象,隨時fetchOnce
被調用時,可以隨時被添加回調(像deferred.done):
model.fetchOnce().done(function() { console.log('model fetched!'); });
似乎是解決方案之一..感謝......看看骨幹網是否具有這樣的內置功能。 –
不幸的是,沒有任何開箱即用的 – mikeapr4
擴展mikeapr4's answer,我做一個簡單的模型,其將覆蓋fetch
功能僅取一次(可選地每X小時)。
它使用jQuery的延遲.state()
function來確定請求是否掛起或完成。
請注意,我使用MomentJS來計算時間差異,但它可以通過JavaScript本機日期輕鬆實現。
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
任意數量的時候,它想要的。
使用它一個簡單的觀點:
var View = Backbone.View.extend({
initialize: function() {
// use the model in case it has been already fetched
this.useModel();
// then fetch anyway to ensure it's fetched
this.listenTo(this.model, 'sync', this.onModelSync);
this.model.fetch();
},
useModel: function() {
// ...use the model data, maybe render here.
}
onModelSync: function() {
// things that need to be done only when model sync succeeded.
this.useModel();
}
});
你爲什麼不取的視野之外的模式?如果你不想讓每個視圖實例執行一些代碼,那麼就不需要在視圖內部進行調用了。 –
其部分視圖只是...但我想只被調用一次...並用於視圖的所有實例。 –
由於您的代碼無法正常工作,因此您需要清楚地指出您在錯誤的地方執行某些操作,並且需要將代碼移至其他地方。如果你可以在渲染控制器中的任何視圖之前獲取數據,你可以達到這個效果,例如 –