计算的可观察量不会更新

时间:2014-07-28 21:33:28

标签: asp.net-mvc knockout.js

我有一个可观察的数组,有4个可观察数据(数量,折扣,费率,税收)和1个计算字段(总计),即(价格*费率) - 折扣+税。当我在数组中添加新项目并更改数量的值,比率等ui更新按预期,但是当初始化视图模型与数据(一些产品)时,对于那些行ui没有更新。

这是我的代码

var pList=@Html.Raw(Json.Encode(Model.ProductList));
        var product = function (item) {

            var self = this;
            this.Qty = ko.observable(0);
            this.Rate = ko.observable(0);
            this.Discount = ko.observable(0);
            this.Tax = ko.observable(0);
            this.Amount = ko.computed(function () {


                return (parseFloat(self.Qty()) * parseFloat(self.Rate())) - parseFloat(  self.Discount() )+ parseFloat( self.Tax());

            },this);


            for (var f in item) {
                self[f] = ko.observable(item[f]);
            }

        };
        var productModel = function (prds) {
            var self = this;
            self.products = ko.observableArray(ko.utils.arrayMap(prds, function (item) {
                return new product(item);
            }));
            self.productList=pList;
            self.addProduct = function () {

                self.products.push(new product());
            };
            self.removeProduct = function (product) {

                self.products.remove(product);

            };
            self.GrossTotal = ko.computed(function () {

                var total = 0;
                for (var i = 0; i < self.products().length; i++) {

                    total += parseFloat( self.products()[i].Amount());
                }
                return total;
            });

        };


        var viewModel = new productModel(@Html.Raw(Json.Encode(Model.Products)));
        ko.applyBindings(viewModel);

HTML:

                            <table class="table grid table-bordered table-hover text-center">
                                <thead>
                                    <tr>
                                        <th>Product</th>
                                        <th>Order Qty</th>
                                        <th>Rate</th>
                                        <th>Discount</th>
                                        <th>Tax</th>
                                        <th>Amount</th>
                                        <th>Remove</th>

                                    </tr>
                                </thead>
                                <tbody data-bind="foreach: products">
                                    <tr>
                                        <td>
                                            <select class="span4 form-control grid" style="min-width: 180px;"
                                                data-bind='options:$root.productList, value:ProductId, optionsText:"Text", optionValue:"Value",attr:{name:"Products["+$index() + "].ProductId"  } '>
                                            </select>
                                        </td>
                                        <td class="span-1">
                                            <input type="text" class="form-control"
                                                data-bind='value:Qty,attr:{ name:"Products["+$index()+"].Qty"  }' />

                                        </td>
                                        <td class="span-1">
                                            <input type="text" class="form-control"
                                                data-bind='value:Rate,attr:{ name:"Products["+$index()+"].Rate"  }' />

                                        </td>
                                        <td class="span-1">
                                            <input type="text" class="form-control"
                                                data-bind='value:Discount,attr:{ name:"Products["+$index()+"].Discount"  }' />

                                        </td>
                                        <td class="span-1">
                                            <input type="text" class="form-control"
                                                data-bind='value:Tax,attr:{ name:"Products["+$index()+"].Tax"  }' />

                                        </td>
                                        <td class="span-1">
                                            <input type="text" class="form-control"
                                                data-bind='value:Amount,attr:{ name:"Products["+$index()+"].Amount"  }' />
                                        </td>
                                        <td class="span-1">
                                            <a href="#" data-bind="click:$root.removeProduct">Remove</a>

                                        </td>
                                    </tr>

                                </tbody>
                                <tfoot>
                                    <tr>
                                        <th>Count : <span data-bind="text: products().length"></span></th>
                                        <th>Qty :<span data-bind="text: TotalQty()"></span></th>
                                        <th></th>
                                        <th>Discount :<span data-bind="text:DiscountTotal()"></span></th>
                                        <th>Tax :<span data-bind="text:TaxTotal()"></span></th>
                                        <th>Amount :<span data-bind="text:NetAmount()"></span></th>
                                        <th></th>

                                    </tr>


                                </tfoot>

                            </table>

这是工作jsfiddle link

任何帮助都会被批评 非常感谢

1 个答案:

答案 0 :(得分:0)

这很可疑:

for (var f in item) {
    self[f] = ko.observable(item[f]);
}

如果项目具有与产品对象上的现有属性匹配的键,则将覆盖可观察属性。然后,计算的observable将最终订阅旧的可观察属性,但新值将存储在新的可观察属性中。这可能解释了这种奇怪的行为。

我建议更新产品上的属性(例如self[f](item[f]))而不是替换observable,或者在定义计算之前使用项中的值作为初始observable的默认值