1
votes

I'm new to knockout.js and am having trouble with a computed observable contained in a constructor function. I'm trying to add instances of "BoughtIns" to my boughtIn observable array in the main viewmodel. This includes qty & price fields (both observables) from which I want to calculate a qxp field.

A fiddle is here: http://jsfiddle.net/glassy10/racvj4c5/37/ - the fiddle works as it stands but fails when the qxp computed observable is uncommented in the html & BoughtIn constructor with an error 'undefined is not a function' which stops the whole thing working.

The html:

<div class="row" data-bind="with:boughtIn">
   <div><input type="text" data-bind="value:item" PlaceHolder ="Item" /></div>
   <div><input type="text" data-bind="value:qty" PlaceHolder ="Qty"/></div>
   <div><input type="text" data-bind="value:price" PlaceHolder ="Price"/></div>
    <div><button data-bind="click:$root.addBoughtIn" >Add Item</button></div>
</div>

<table>
    <thead>
        <tr>
            <th>Item</th>
            <th>Qty</th>
            <th>Price</th>
            <th>Q x P</th>
            <th></th>
        </tr>
    </thead>
    <tbody data-bind="foreach:boughtIns">
        <tr>
            <td data-bind="text:item"></td>
            <td data-bind="text:qty"></td>
            <td data-bind="text:price"></td>
            <td>
                <span data-bind="text:qxp"></span>
            </td>
            <td><a href="#" data-bind="click:$root.deleteBoughtIn">Delete</a></td>
        </tr>
    </tbody>
</table>

The js:

var ViewModel = function() {
    var self = this;
    //other observables
    //...
     //boughtIns
    self.boughtIns = ko.observableArray([]);
    self.boughtIn = ko.observable(new BoughtIn());

    self.addBoughtIn = function(data) {
        self.boughtIns.push(data);
        //reset to clear fields
        self.boughtIn(new BoughtIn());
    };
    self.deleteBoughtIn = function(data) {
        self.boughtIns.remove(data);
    };
}

function BoughtIn() {
    var self = this;
    self.item = ko.observable(),
    self.qty = ko.observable(),
    self.price = ko.observable(),
    self.category = ko.observable(),
    //NOT WORKING ----
    self.qxp = ko.pureComputed( {
        read: function () { return self.qty() * self.price(); },
        deferEvaluation: true
    })
    //----------------
}

ko.applyBindings(new ViewModel());
1
try using ko.computed may be purecomputed dont exist in the 3.0 thats why you get undefined - super cool
Excellent..thank you - Howard Shaw

1 Answers

3
votes

As per the Docs here pureComputed introduced in Knockout 3.2.0 .

You are refering to a fiddle with a version of 3.0 which make pure computed undefined .

Try with Ko.computed which works fine .

View Model:

 self.qxp = ko.computed({
        read: function () { return self.qty() * self.price(); },
        deferEvaluation: true
    })

Working fiddle here