简体   繁体   English

Knockout中可重用的计算字段

[英]Reusable Computed Fields in Knockout

I have a Knockout Viewmodel that uses the mapping plugin. 我有一个使用映射插件的Knockout Viewmodel。 After mapping the JSON object, I create some computed values, like so: 映射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        
});

Don't worry so much about what the code does, I'm more concerned with the pattern. 不要太担心代码的作用,我更关心模式。 As you can see, the two properties formattedGiftAmount() and formattedGoal() have nearly identical objects that define them. 正如您所看到的,两个属性formattedGiftAmount()formattedGoal()具有几乎相同的对象来定义它们。 The only difference is what properties they modify. 唯一的区别是他们修改了哪些属性。 I'm potentially going to have many more instances like this, so I was wondering if there was any way to make this more reusable. 我可能会有更多像这样的实例,所以我想知道是否有任何方法可以使它更可重用。 I can imagine doing something like this[prop]() , but I can't quite figure out how to inject that into the object and get it to work. 我可以想象做这样的事情this[prop]() ,但是我无法弄清楚如何将它注入到对象中并使其工作。

PS: I've seen this but it still doesn't quite do what I'm looking for. PS:我已经看过这个,但它仍然不能完全满足我的需求。

You can also modify fn to add a function to your ko.observable to create it, this will allow you to add the properties in your constructor in a descriptive way ( fiddle ): 您还可以修改fn以向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();
};

You can add a function to your view model that creates a formatted property based on an unformatted property: 您可以向视图模型添加一个函数,该函数基于未格式化的属性创建格式化属性:

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

Then you could call it for your properties: 然后你可以为你的房产调用它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM