2013-05-14 58 views
3

使用KnockOut - 我試圖在添加到MVC .Net代碼之前構建主要細節/項目應用程序的基礎知識。KnockOut的計算功能問題

所有我想要做的是有一個簡單的項目,價格,稅收 - 併爲計算欄,顯示的金額含稅每個項目:

客戶端淘汰賽視圖模型是:

var GiftModel = function(gifts) { 
var self = this; 
self.gifts = ko.observableArray(gifts); 

self.formattedPrice = ko.computed(function() { 
    var pricet = self.gifts().price; 
    return pricet ? "$" + pricet.toFixed(2) * (1 + self.gifts().tax : "None"; 

});  

self.addGift = function() { 
    self.gifts.push({ 
     name: "", 
     price: "", 
     tax:0 
    }); 
}; 

self.removeGift = function(gift) { 
    self.gifts.remove(gift); 
}; 

self.save = function(form) { 
    alert("Could now transmit to server: " + ko.utils.stringifyJson(self.gifts)); 
    // To actually transmit to server as a regular form post, write this: ko.utils.postJson($("form")[0], self.gifts); 
}; 
}; 

var viewModel = new GiftModel([ 
{ name: "Tall Hat", price: "39.95", tax:17.5}, 
{ name: "Long Cloak", price: "120.00", tax:20} 
]); 
ko.applyBindings(viewModel); 

// Activate jQuery Validation 
$("form").validate({ submitHandler: viewModel.save }); 

表格標記是:

<table data-bind='visible: gifts().length > 0'> 
     <thead> 
      <tr> 
       <th>Gift name</th> 
       <th>Price</th> 
       <th>Tax</th> 
       <th /> 
      </tr> 
     </thead> 
     <tbody data-bind='foreach: gifts'> 
      <tr> 
       <td><input class='required' data-bind='value: name, uniqueName: true' /></td> 
       <td><input class='required number' data-bind='value: price, uniqueName: true' /></td> 
       <td><input class='required number' data-bind='value: tax, uniqueName: true' /></td> 
       <td data-bind='text: formattedPrice'></td> 
       <td><a href='#' data-bind='click: $root.removeGift'>Delete</a></td> 

      </tr> 
     </tbody> 
    </table> 

    <button data-bind='click: addGift'>Add Gift</button> 
    <button data-bind='enable: gifts().length > 0' type='submit'>Submit</button> 

它拖延爲formattedPrice功能犯規似乎是工作。

我已經在一個jsfiddle這裏:http://jsfiddle.net/marktait/TR6Sy/ - 任何人都可以幫助我克服這個看似簡單的障礙嗎?

謝謝

馬克

回答

4

的問題是,您所呼叫的comouted功能,通過送禮名單上循環。然而,計算出的方法不適用於給定的禮物,而是適用於所有禮物。你有兩個選擇:

要麼你做到這一點,以便每個禮物對象都是這個計算方法的對象(就像用戶布蘭登建議的那樣),或者你只是將它轉換爲一個普通函數,這樣的:

self.getFormattedPrice = function(price, tax) { 
    var val = price ? "$" + parseFloat(price).toFixed(2) * (1 + tax) : "None"; 
    return val; 
};  

然後,你這樣稱呼它:

<td data-bind='text: $parent.getFormattedPrice(price, tax)'></td> 

我已經更新您的fiddle

+0

嗨 - 謝謝你。我認爲增加一條線並改變任何內容(即文本框中的稅額)會很簡單,並且會自動重新計算含稅價格。我可能一直期待太多。謝謝你的時間。 – Mark 2013-05-14 13:38:33

+0

沒問題,樂意幫忙! – Jalayn 2013-05-14 13:40:07

0

看起來你只是缺少一個右括號 -

return pricet ? "$" + pricet.toFixed(2) * (1 + self.gifts().tax : "None"; 

應該

return pricet ? "$" + pricet.toFixed(2) * (1 + self.gifts().tax) : "None"; 
+0

嗨 - 我補充說,但同樣的事情發生 - 它顯示最初的一行,然後沒有更多(從JSON數據) - 並點擊添加禮物ives 404錯誤。謝謝,馬克 – Mark 2013-05-14 13:16:49

2

self.gifts()是一個數組。但在你的計算中,你試圖將它用作單一值。這是行不通的。你需要把它作爲一個計算的屬性添加到每個項目在數組中:

var addFormattedPrice = function (gift) { 
    gift.formattedPrice = ko.computed(function() { 
     var pricet = gift.price; 
     return pricet ? "$" + pricet.toFixed(2) * (1 + gift.tax : "None"; 
    }); 
}; 

ko.utils.arrayForEach(self.gifts(), addFormattedPrice); 

self.addGift = function() { 
    var gift = { 
     name: "", 
     price: "", 
     tax:0 
    }; 
    addFormattedPrice(gift); 
    self.gifts.push(gift); 
}; 
+0

嗨 - 我補充說,並更新小提琴:http://jsfiddle.net/marktait/TR6Sy/6/ - 它仍然沒有顯示第二行,或允許任何更多的添加(404錯誤再次)。 – Mark 2013-05-14 13:30:30