2012-03-09 114 views
17

我有一個場景,其中在客戶端上操作的數據以不同於服務器上表示的方式呈現並與其交互。Backbone中的計算屬性

考慮從服務器返回的以下event資源。

{ 
    "id": 123, 
    "start_at": 1331336004906, 
    "end_at": 1331337704906 
} 

以及編輯下面的模板:

<form> 
    <!-- Notice how date and time are separated in the interface --> 
    <input type="text" name="start_date" value="{{start_date}}" /> 
    <input type="text" name="start_time" value="{{start_time}}" /> 

    <!-- Instead of asking for an end date/time, we ask for the duration --> 
    <input type="text" name="duration" value="{{duration}}" /> 

    <input type="submit" /> 
</form> 

我怎麼會去治療start_datestart_timeduration因爲沒有將它們發送到服務器,我的骨幹模型屬性?我應該修改.toJSON()嗎?

+0

什麼是與事件的ressource格式的問題,他們的arent時間戳? – mpm 2012-03-09 23:48:12

+0

另請參閱:http://stackoverflow.com/questions/10648990/how-to-access-a-calculated-field-of-a-backbone-model-from-handlebars-template – 2014-07-17 22:39:35

回答

4

您的模型應該儘可能與您擁有的服務器端一致。所以堅持start_atend_at。這將大大簡化您的sync()操作。

在您編輯表單的查看,您可以:

  1. 計算start_datestart_timeduration通過簡單的功能,並呼籲他們在模板中。
  2. 提交時轉換爲start_atend_at
+1

是不是把這個在視圖中會導致很多冗餘代碼?我將在整個網站上使用相同的虛擬屬性,其中一個事件具有多個顯示它的視圖。 – bloudermilk 2012-03-10 01:33:15

+0

沒有必要的冗餘。製作基本視圖並對其進行擴展。 – ggozad 2012-03-10 08:37:35

+1

良好的通話!我也認爲裝飾者模式可以適應這個問題。 – bloudermilk 2012-03-10 09:16:02

6

我們很用來發送model.toJSON()喂模板。而且這種方法很難覆蓋,因爲被其他組件使用。

但是,我們可以養活一個自定義model.toJSONDecorated()方法的模板可以是這樣的:

# in your Backbone.Model 
toJSONDecorated: function(){ 
    return 
    _.extend( 
     this.toJSON(), 
     { 
     start_date : Utils.dateFromDate(this.get("start_at")), 
     start_time : Utils.timeFromDate(this.get("start_at")), 
     duration : Utils.youGetTheIdea(:)) 
     } 
    ); 
} 

當然,這是打破了幾個模式,我可以住在一起,如果你沒有,你可以正如人們在其他答案中所建議的那樣,將此邏輯移至Decorator類。

5

你有一些選擇:

  • 覆蓋toJSON返回計算duration

  • 的骨幹Model創建duration()方法。唯一不利的是,您必須以不同的方式調用它(obj.duration()而不是obj.get('duration'))。在你認爲手obj.toJSON()到您的模板,拌入duration屬性

  • 使用https://github.com/asciidisco/Backbone.Mutators(或類似)來創建一個派生的getter的時間

+0

謝謝。我通常採用描述的方法,但我不知道Mutators:它看起來非常有用,做得很好。 – 2015-01-08 08:49:27

22

我使用的初始化的組合()與更改事件偵聽器一起使用以更新派生屬性。這個想法是首先計算模型初始化的屬性,其次是讓模型監聽它自己的變化並相應地更新屬性。

我的解決方案看起來大致是這樣的:

MyModel: Backbone.Model.extend({ 
    initialize: function() { 
     this.updateDerivedAttributes(); 
     this.on('change:start_at', this.updateDerivedAttributes, this); 
    }, 
    updateDerivedAttributes: function() { 
     this.set({ 
      start_date: Utils.dateFromDate(this.get("start_at")), 
      start_time: Utils.timeFromDate(this.get("start_at")), 
      duration: Utils.youGetTheIdea() 
     }, {silent:true}); 
    } 
});