我有一个项目集合,我想显示每个项目的总数和个别百分比。问题似乎是我在计算总数时需要父对象的引用。所以我想我将为集合定义一个计算得到的 getTotal 并为项目定义一个百分比。
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 总是空的。由于某种原因,推送它不会触发要重新计算的项目。
这也是这样做的正确方法吗?我现在可以弄清楚如何在为每个子项提供对父对象的引用的同时在 Collection 中创建一个 observableArray。
最佳答案
- 您的 getTotal 应该返回金额的总和,而不是部分的数量,对吧?
- 您不必将元素一个一个地推送到各个部分。你可以做 collection.parts($.map([40, 50, 30], function(el){return new Part(el, collection);});) (我这里用的是jQuery.map)
- 总的来说,我认为百分比不属于 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>
关于javascript - Knockout - 如何同时为子项和父项设置计算属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9200834/