2012-05-29 22 views
2

我有一個使用映射插件的Knockout Viewmodel。映射JSON對象後,我創造了一些計算值,就像這樣:Knockout中的可重用計算域

/* viewmodel setup and mapping */ 

myViewModel 
    .formattedGiftAmount = ko.computed({ 
     read: function() { 
      return parseInt(this.giftAmount(), 10).formatMoney();       
     } 
     , write: function (value) {       
      this.giftAmount(value.unformatMoney()); 
     } 
     , owner: this   
    }) 
    .formattedGoal = ko.computed({ 
     read: function() { 
      return parseInt(this.goalAmount(), 10).formatMoney();       
     } 
     , write: function (value) {       
      this.goalAmount(value.unformatMoney()); 
     } 
     , owner: this   
}); 

不要太在乎的代碼做什麼,我更關心的格局。正如你所看到的,兩個屬性formattedGiftAmount()formattedGoal()具有幾乎相同的對象來定義它們。唯一的區別是它們修改了哪些屬性。我可能會有更多這樣的實例,所以我想知道是否有什麼方法可以使它更加可重用。我可以想象做類似this[prop]()的東西,但我不能完全弄清楚如何將其注入到對象中並使其運行。

PS:我見過this,但它仍然不完全符合我的要求。

回答

2

您可以添加一個函數來創建基於一個未格式化的屬性格式化性質的視圖模型:

myViewModel.addFormattedProperty = function(formattedName, unformattedName) { 
    this[formattedName] = ko.computed({ 
     read: function() { 
      return parseInt(this[unformattedName](), 10).formatMoney();       
     }, 
     write: function(value) { 
      this[unformattedName](value.unformatMoney()); 

     }, 
     owner: this 
    }); 
}; 

然後,你可以叫它爲您的屬性:

myViewModel.addFormattedProperty('formattedGiftAmount', 'giftAmount'); 
myViewModel.addFormattedProperty('formattedGoalAmount', 'goalAmount'); 
7

你也可以modify fn將函數添加到您的ko.observable中以創建它,這將允許您以描述性方式在構造函數中添加屬性(fiddle):

ko.observable.fn.formatAsMoney = function() { 
    var base = this; 
    return ko.computed({ 
     read: function() { 
      return formatMoney(parseFloat(base())); 
     }, 
     write: function(newValue) { 
      base(unformatMoney(newValue)); 
     } 
    }); 
}; 

function ViewModel() { 
    var self = this; 
    self.number = ko.observable(10.5); 
    self.money = self.number.formatAsMoney(); 
}; 
+0

+1!這是一個很好的方法,謝謝:) –