0
votes

This is inside a Durandal app. I've got an observable array called Items, and each item has some properties and a ko.computed value of linetotal.

    self.items = ko.observableArray();
    self.item = function(data) {
        this.sku = ko.observable(data.sku);
        this.description = ko.observable(data.description);
        this.msrp = ko.observable(data.msrp)
        this.sell_price = ko.observable(data.sell_price);
        this.quantity = ko.observable(data.quantity);
        this.tax = ko.observable(data.tax);
        this.linetotal = ko.computed(function() {
            return Number(this.sell_price()) * Number(this.quantity());
        }, this);
    }

    self.activate = function () {
        //make an empty item row
        self.items.push(new self.item({
            sku: "",
            description: "",
            msrp: "",
            sell_price: "2.41",
            quantity: "3",
            tax: "",
        }));

    }

On page activation, I get the expected value of 7.23 in the line total field:

        <tbody data-bind="foreach: items">
          <tr>
            <td><input type="text" data-bind="attr: { value: $data.sku }"></td>   
            <td><input type="text" data-bind="attr: { value: $data.description }"></td>               
            <td><input type="text" data-bind="attr: { value: $data.msrp }"></td>
            <td><input type="text" data-bind="attr: { value: $data.sell_price }"></td>
            <td><input type="text" data-bind="attr: { value: $data.quantity }"></td>
            <td><input type="text" data-bind="attr: { value: $data.tax }"></td>
            <td data-bind="text: $data.linetotal"></td>           
          </tr>
        </tbody>

But it appears that the computed function is not bound to observables, since updating the quantity or sell_price fields does not change the computed value. I can post a js fiddle, but it won't be functional since this is inside of a Durandal app.

Here it is: https://jsfiddle.net/1zcfz1ax/

Am I approaching the problem wrong?

1
When you post a fiddle, strip it down to just the problem. Things like this are rarely dependent on the environment in which they are running. I've taken the liberty of doing this for you in my answer below. - caseyWebb

1 Answers

1
votes

Use the value binding, not attr: { value: foo }

Here's a cleaned up fiddle.

I've pulled the Item "class" out of the viewmodel since it doesn't need to be there, removed the superfluous $data.foo bindings in favor of simply foo, changed the values to regular numbers rather than strings, so you don't have to cast them to numbers later.