我有如下代码:
// First we define our gift class,which has 2 properties: // a Title and a Price. // We use knockout js validation to ensure that the values input are suitable/ function Gift(item) { var self = this; self.Title = ko.observable(item.Title); // attach some validation to the Title property courtesy of knockout js validation self.Title.extend({ required: true,minLength: 3,pattern: { message: 'At least ',params: '^[a-zA-Z]+\s?[a-zA-Z]*' } }); self.Price = ko.observable(item.Price); self.Price.extend({required:true,number:true,min:0.1,max:1000}); }; var viewmodelForTemplated = { gifts: ko.observableArray(),// gifts will be an array of Gift classes addGift: function () { this.gifts.push(new Gift({ Title: "",Price: "" })); },removeGift: function (gift) { this.gifts.remove(gift); },totalCost: ko.computed(function () { if (typeof gifts == 'undefined') return 0; var total = 0; for (var i = 0; i < gifts().length; i++) { total += parseFloat(gifts()[i].Price()); }; return total; }) } $(document).ready(function () { // load in the data from our MVC controller $.getJSON("gift/getdata",function (allGifts) { var mappedgifts = $.map(allGifts,function (gift) { return new Gift(gift); }); viewmodelForTemplated.gifts(mappedgifts); }); ko.applyBindings(viewmodelForTemplated,$('#templated')[0]); }
然后(脚本上面)
<div id="templated"> <table > <tbody data-bind="template: { name: 'giftRowTemplate',foreach: gifts }"></tbody> </table> <script type="text/html" id="giftRowTemplate"> <tr> <td>Gift name: <input data-bind="value: Title"/></td> <td>Price: \$<input data-bind="value: Price"/></td> <td><a href="#" data-bind="click: function() { viewmodelForTemplated.removeGift($data) }">Delete</a></td> </tr> </script> <p>Total Cost <span data-bind="text: totalCost"></span> </p> <button data-bind="click: addGift">Add Gift</button> <button data-bind="click: save">Save</button> </div>
totalCost方法只运行一次,当礼物数组为空时,我可以将项目推送或删除到observableArray()中,但没有任何问题.
如何获取参考totalCost更新的跨度?我打赌这是一个简单的事情:)
谢谢你的帮助.
解决方法
你需要展开你的观察:
totalCost: ko.computed(function () { //also,you forgot typeof below if (typeof gifts == 'undefined') return 0; var total = 0; //here \/ for (var i=0; i < gifts().length; i++) { //and here \/ total += parseFloat(gifts()[i].Price()); }; return total; })
它不是更新的原因是因为
gifts.length
总是评估为0,永远不会进入循环.即使如此,
gifts[i].Price()
不会因为同样的原因而工作你需要展开可观察的.
请注意,当您不解开时,长度评估为零的原因是因为您获得了length of the actual observable array function. Knockout中的所有可观察值都被实现为常规函数;当你不打开它,你正在击中实际的功能本身,而不是底层的数组.
编辑,
此外,您需要使用此赠品参考礼品,因为它是一个对象属性.这就是为什么这不工作;礼物一直没有定义.
也就是说,你还需要做一些更多的工作来让ko计算机从一个对象字面上工作.在这里阅读更多信息:
http://dpruna.blogspot.com/2013/09/how-to-use-kocomputed-in-javascript.html
以下是我将如何使您的视图模型:
function Vm{ this.gifts = ko.observableArray(); // gifts will be an array of Gift classes this.addGift = function () { this.gifts.push(new Gift({ Title: "",Price: "" })); }; this.removeGift = function (gift) { this.gifts.remove(gift); }; this.totalCost = ko.computed(function () { var total = 0; for (var i = 0; i < this.gifts().length; i++) { total += parseFloat(this.gifts()[i].Price()); }; return total; },this); } var viewmodelForTemplated = new Vm();