Frage

I have a Knockout Viewmodel that uses the mapping plugin. After mapping the JSON object, I create some computed values, like so:

/* 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. 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.

PS: I've seen this but it still doesn't quite do what I'm looking for.

War es hilfreich?

Lösung

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

Andere Tipps

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):

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();
};
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top