Karthik Renkarajan
Karthik Renkarajan

Reputation: 29

Setting default values for computed Observable Knockout.js

I am new to Knockout.js I have 3 fields in the UI . Product value. Quantity Total

Everything works fine with the computed observable and could save the data.The total will be changed in the backend for some business reasons.

While retrieving the data back,I need to show the total from the DB as initial value,but when the user chnages the product and value ,the original computed function should be used.

I tried bindingHandlers but could not get it right..

Help would be highly appreciable.

var TsFoundationDeviceModel = function(product,qty,total) {
    var self = this;
    self.product = ko.observable(product);
    self.quantity= ko.observable(qty);
    self.computedExample = ko.computed(function() {
        return self.product() * self.quantity() ;
    });
}

<input name="product" data-bind="value:product">
<input name="value" data-bind="value:value">
<input name="total" data-bind="value:computedExample"/>

Upvotes: 0

Views: 7748

Answers (3)

Sujesh Arukil
Sujesh Arukil

Reputation: 2469

The only way you can do this is by keeping track of an initializer. So the first time you call your viewmodel, you set the initialize to true and check if the total is not undefined. If so, return total, reset initialize. From there on, it will always update the computed based on the other two fields.

Here is the fiddle for the same (by the way, there is an error in your bindings, there is no property by the name "value", I assumed it is quantity

http://jsfiddle.net/sujesharukil/YTDZ9/

var TsFoundationDeviceModel = function(product,qty,total) {
    var 
    self = this;
    self.initialize = ko.observable(true);
    self.product = ko.observable(product);
    self.quantity= ko.observable(qty);
    self.computedExample = ko.computed(function() {
        var value = self.product() * self.quantity();
        if(self.initialize())
        {
            self.initialize(false);
            if(total != undefined && total != null)
                return total;
        }
        return value ;
    });
}


ko.applyBindings(new TsFoundationDeviceModel(1, 1, 3));

in essensce, you will be returning total only once, the very first time you create an instance of your viewmodel.

Hope this helps!

-Suj

Upvotes: 3

Joel Cochran
Joel Cochran

Reputation: 7748

If I understand what you want correctly, you could have the Computed itself return the initial value unless the observables change.

self.product = ko.observable(product);
self.quantity= ko.observable(qty);
self.orig_product = ko.observable(product);
self.orig_quantity= ko.observable(qty);

self.computedExample = ko.computed(function() {
    if (self.product() !== self.orig_product
        || self.quantity() !== self.orig_quantity()) {
        return self.product() * self.quantity() ;
    } else {
        // return the initial value
    }
});

Upvotes: 0

ebram khalil
ebram khalil

Reputation: 8321

AS far as i can get from you is that you store 3 inputs that you get it's value from the DB.

When the user click on some save button the data should be sent to the server to update or insert in DB, and when the form is loaded the inputs should be populated with user data from DB.

So you should use for that purpose KnockoutJS mapping plugins.

using that plugin you just need to make ajax call to your server to get the data and convert it into ViewModel then use apply that ViewModel on your html.

and by using the same plugin you can convert your ViewModel into JSON format and send it back to your server to save it in DB.

Upvotes: 0

Related Questions