0

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"/>
Joel Cochran
  • 7,139
  • 2
  • 30
  • 43
  • please post your code or what you have tried. – ebram khalil Mar 14 '13 at 23:33
  • so the problem is when you get the data back from DB or when the user update the inputs values ?? – ebram khalil Mar 14 '13 at 23:38
  • The problem is how do I set the data(ie total) that I get from the server along with product value and Quantity but Knockout should not do the compute initially since total is a computed field.It should just show the total value I get from the server and when the user chnages something in ProductValue and quantity,thats when the values should change. – Karthik Renkarajan Mar 14 '13 at 23:41
  • To make it right,how to set the default value for the computed field when the page is loaded,but as the dependable value ie product value and quantity changes,the computed function should be triggered. – Karthik Renkarajan Mar 14 '13 at 23:43

3 Answers3

3

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

Sujesh Arukil
  • 2,469
  • 16
  • 37
0

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.

ebram khalil
  • 8,252
  • 7
  • 42
  • 60
  • Thanks Ebram.I have no problems doing that but in my example,when I get the total value,how can I assign that value to the total.Right now it will be calcualted based on product and value,which as per my requirement should not happen when the page is loaded or until the user chnages something in product or value. – Karthik Renkarajan Mar 14 '13 at 23:52
  • from Knockoutjs documentation "computed observables are functions that are dependent on one or more other observables, and will automatically update whenever any of these dependencies change." – ebram khalil Mar 14 '13 at 23:55
  • I am struggling to set the default value from the server to the total input..Other than that,everything is ok..Can someone help on this ? – Karthik Renkarajan Mar 14 '13 at 23:57
  • OK how you apply the data coming from server to your html? – ebram khalil Mar 15 '13 at 00:00
  • for Product and value , I just call like this TsFoundationDeviceModel(10,20) and for total I can pass another argument but need to crack a way to pass it to computed function. – Karthik Renkarajan Mar 15 '13 at 00:07
0

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
    }
});
Joel Cochran
  • 7,139
  • 2
  • 30
  • 43