简体   繁体   中英

knockout computed not being updated

I am trying to create a computed observable and display it on the page, and I have done it this way before but I am starting to wonder if knockout has changed - Everything works except the binding on totalAmount - for some reason it never changes...Any ideas?

My model is as follows:

var cartItem = function(item){
    this.itemName = item.title;
    this.itemPrice = item.price;
    this.itemID = item.id;
    this.count=0;
}
var cartModel = {
    self:this,
    footers:ko.observableArray([{title:'item1',text:'this is item1 text',image:'images/products/items/item1.png',price:15.99,id:1},
    {title:'item2',text:'this is item2 text',image:'images/products/items/item2.png',price:25.99,id:2},
    {title:'item3',text:'this is item3 text',image:'images/products/items/item3.png',price:55.99,id:3},
    {title:'item4',text:'this is item4 text',image:'images/products/items/item4.png',price:5.99,id:4},

]),
cart:ko.observableArray([]),
addToCart:function(){
if(cartModel.cart().length>0){
        for(var i=0;i<cartModel.cart().length;i++){
            if(this.id==cartModel.cart()[i].itemID){
                cartModel.cart()[i].count += 1;
            }
            else{
                cartModel.cart().push(new cartItem(this));
            }
        }
    }else{
        cartModel.cart().push(new cartItem(this));
    }
    console.log(cartModel.cart().length);  
}
}
this.cartModel.totalAmount=ko.computed(function(){
    return this.cart().length;    
},this.cartModel);
ko.applyBindings(cartModel);

And here is the associated HTML:

<div data-bind="template:{name:'footerTemplate',foreach:cartModel.footers}">
    <script type="text/html" id="footerTemplate">
        <div class="row">
            <span class="span2"><h3 data-bind="text: title"></h3></span>
            <span class="span2"><img data-bind="attr:{src: image}"/></span>
            <span class="span5" data-bind="text:text"></span>
            <span class="span1" data-bind="text:price"></span>
            <spand class="span2"><button data-bind="click:$parent.addToCart">add</button></span>
        </div>
    </script>
</div>
<div class="row">
    <span class="span2" data-bind="text:totalAmount"></span>
</div>

You are calling the push method on the internal array, not on the observableArray wrapper, thus the changes are never notified.

ie instead of:

cartModel.cart().push(new cartItem(this));

use simply:

cartModel.cart.push(new cartItem(this));

For more info take a look at the official documentation for observableArray, and in particular at the Reading information from an observableArray and Manipulating an observableArray sections.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM