2012-02-08 54 views
3

我有一個項目的集合,我想顯示總計以及每個項目的個別百分比。問題似乎是在計算總數時需要父對象的引用。所以我想我會爲集合定義一個計算的getTotal,併爲該項目定義一個百分比。Knockout - 如何爲同一時間的孩子和父母設置計算屬性?

function Collection() { 
    var self = this; 
    self.parts = ko.observableArray(); 
    self.getTotal = ko.computed(function() { 
     var total = self.parts.length; 
     return total; 
    }); 
} 

function Part(amount, parent) { 
    var self = this; 
    self.amount = ko.observable(amount); 
    self.parent = parent; 

    self.percentage = ko.computed(function() { 
     return self.amount()/self.parent.getTotal(); 
    }); 
} 

var partsData = [40, 50, 30]; 
var collection = new Collection(); 
for (var i = 0; i < partsData.length; ++i) { 
    collection.parts.push(new Part(partsData[i], collection)); 
} 

ko.applyBindings(collection); 

而我的HTML是

<ul data-bind="foreach: parts"> 
    <li> 
     <p data-bind="text: amount"></p> 
     <p data-bind="text: percentage"></p> 
    </li> 
</ul> 

然而Collection.parts總是空的。出於某種原因推動它不會觸發重新計算的項目。

也是這樣做的正確方法嗎?我現在可以弄清楚如何在集合中同時創建一個observableArray,同時爲每個子項提供對父對象的引用。

回答

6
  1. 你的getTotal應該返回金額的總和,而不是零件的數量,對不對?
  2. 您不必將元素逐個推送到零件。你可以做collection.parts($。map([40,50,30],function(el){return new Part(el,collection);});) (我在這裏使用jQuery.map)
  3. In一般我認爲百分比不屬於Part,因爲它必須通過一個集合,這是不好的(不必要的依賴)。我會做它,而不是這樣:
function ViewModel() { 
    var self = this; 
    self.parts = ko.observableArray([]); 
    self.total = ko.computed(function(){ 
     var s = 0; 
     $.each(self.parts(), function(i, el){s += el.amount();}); 
     return s; 
    }); 
} 

function Part(amount){ 
    this.amount = ko.observable(amount); 
} 

$(function() { 
    var view = new ViewModel(); 
    var parts = $.map([40, 50, 30], function(el){return new Part(el);}); 
    view.parts(parts); 
    ko.applyBindings(view); 
}); 

HTML:

<ul data-bind="foreach: parts()"> 
    <li> 
     <p data-bind="text: amount"></p> 
     <p data-bind="text: amount()/$root.total()"></p> 
    </li> 
</ul> 
+0

這將正常工作。我認爲在Part對象上離散表示百分比而不是在視圖中計算它是一個好的選擇。你做這件事的方式很好。事實上,你甚至可以刪除'self.parent',並直接在你的計算observable中直接使用'parent',因爲它將包含在你傳遞給你計算的observable的函數所創建的閉包中。 – 2012-02-08 21:14:21

+0

我同意最初的代碼是好的,但如果你只需要顯示一個百分比,我寧願不在Part和Collection之間引入額外的依賴關係。對於其他一些不屬於問題組成部分的東西可能會有用。 – 2012-02-08 21:32:03

+0

我之所以把百分比放在零件上是因爲它們會隨着大量的屬性和功能而增長。最終,我打算創建將模仿我的對象模型的Javascript模型,這是有道理的。我想我錯過了把()放在計算函數中的屬性上,並打破了它。完全稱讚羅馬。 – 2012-02-08 22:18:16