0

我有一個視圖的多個實例,它們之間共享單個模型實例。當多個視圖共享相同模型時,骨幹視圖呈現期間的單個服務器調用

在渲染視圖的過程中,我想調用模型中的一個函數,使服務器調用一次只提取一些數據。

由於這些視圖是相同視圖的實例,它們都觸發模型內部的函數。因此進行多個服務器調用。
任何想法如何我只能在模型內部觸發此功能一次。

+1

你爲什麼不取的視野之外的模式?如果你不想讓每個視圖實例執行一些代碼,那麼就不需要在視圖內部進行調用了。 –

+0

其部分視圖只是...但我想只被調用一次...並用於視圖的所有實例。 –

+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; 
}, 

這將節省請求被調用時,獲取並避免任何額外的呼叫,而當前的請求是正在進行的,或者如果它已成功完成。

由於jqXHR對象是Deferred Promise對象,隨時fetchOnce被調用時,可以隨時被添加回調(像deferred.done):

model.fetchOnce().done(function() { console.log('model fetched!'); }); 
+0

似乎是解決方案之一..感謝......看看骨幹網是否具有這樣的內置功能。 –

+1

不幸的是,沒有任何開箱即用的 – mikeapr4

0

擴展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(); 
    } 
});