Search code examples
knockout.jsknockout-mapping-plugin

overriding a JSON property to be computed


I am brand spanking new to knockout.js so forgive if this is a trivially easy question.

I am getting JSON data from a web service that already contains a property that needs to be computed. Something like

{
    ValueA: 1,
    ValueB: 3,
    SumOfValues: 0
}

SumofValues needs to be the sum of ValueA and ValueB. I want to use the mapping plugin to create my viewmodel, but override the creation of SumOfValues so that it is computed. When the Viewmodel is converted back into JSON data (for posting back to the web service), I want SumOfValues to contain the correct sum.

I have this working pretty well in this jsfiddle, the only problem is that the SumofValues property doesn't update when I change the value in one of the textboxes. I thought this value would automatically be dependent on ValueA and ValueB because I reference them in the function.

thanks


Solution

  • You need to change your mapping of SumOfValues to create a computed value rather than an observable value. Here is an updated fiddle that does this:

    http://jsfiddle.net/38MwU/11/

    and the code:

    var json = {
    "ValueA": 9,
    "ValueB": 1,
    "SumOfValues": 0
    };
    
    function myViewModel(data) {
    var self = this;
    
    var mapping = {
        'SumOfValues': {
            create: function (options) {
                return ko.computed( function() {
                    return (parseInt( self.ValueA() ) + parseInt( self.ValueB() ) );
                });
            }            
        }
    };
    
    ko.mapping.fromJS(data, mapping, self);
    
    self.isValid = ko.computed(function () {
        return (self.SumOfValues() == self.ValueA() + self.ValueB() ? "equal" : "not equal");
    });
    }
    
    ko.applyBindings(new myViewModel(json));