Javascript 敲除中可重用的计算字段

Javascript 敲除中可重用的计算字段,javascript,mvvm,knockout.js,computed-observable,Javascript,Mvvm,Knockout.js,Computed Observable,我有一个使用mapping插件的Knockout Viewmodel。映射JSON对象后,我创建了一些计算值,如下所示: /* viewmodel setup and mapping */ myViewModel .formattedGiftAmount = ko.computed({ read: function () { return parseInt(this.giftAmount(), 10).formatMoney();

我有一个使用mapping插件的Knockout Viewmodel。映射JSON对象后,我创建了一些计算值,如下所示:

/* 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()
具有几乎相同的对象来定义它们。唯一的区别是它们修改了哪些属性。我可能会有更多这样的实例,所以我想知道是否有任何方法可以使它更易于重用。我可以想象这样做,比如
这个[prop]()
,但是我不太明白如何将它注入到对象中并使其工作


PS:我已经看到了,但它仍然没有达到我想要的效果。

您可以在视图模型中添加一个函数,该函数基于未格式化属性创建格式化属性:

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');
您还可以向ko.observable添加函数来创建它,这将允许您以描述性的方式在构造函数中添加属性():

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