我正在使用MVVM模式breeze.js和knockout.js开发MVC Web应用程序。这是我第一次使用这些js库,我仍然需要掌握它们的工作原理。
该应用程序的一个页面有一个网格,其中列和行都是动态生成的。我需要添加一个额外的列,其中每行我都有以下行单元格中显示的总值。这是一个例子:
Data type | Comment | Fact 1 | Fact 2 | Total | Value 1 | Value 2 | Value 3 | Value 4
==============================================================================================
Item 1 | any comment | fact 1 | fact 2 | calc. sum | 10 | 20 | 30 | 40
通过将breeze实体对象(planningItems)绑定到模板来生成网格。该对象具有DataTypeId,Comment,Member,Total,FactValues属性。总计是计算的总和。
<script type="text/html" id="list-planning-template">
<tr data-bind="mouseOverButton: $data">
<td style="text-align: center">
<button class="actionbutton actionbutton-item" data-bind="selectItem: $root.selectedItems, itemId: FactId"></button>
</td>
<td data-bind="text: DataTypeId" />
<td data-bind="text: Comment().Text" />
<!-- ko foreach: FactMembers -->
<td data-bind="text: Member().Code"></td>
<!-- /ko -->
<td data-bind="text: Total" />
<!-- ko foreach: FactValues -->
<td style="width: 50px" data-bind="text: Value"></td>
<!-- /ko -->
</tr>
我一直试图通过以下列方式扩展breeze实体对象来添加Total属性:
var FactCtor = function () {
this.Total = ko.computed({
read: function () {
var sum = 0;
if (this.FactValues) {
this.FactValues().forEach(function (fv) {
sum += fv.Value();
});
}
return sum;
},
deferEvaluation: true
}, this);
};
manager.metadataStore.registerEntityTypeCtor("Fact", FactCtor);
本质上,此代码应该做的是通过添加具有延迟评估的名为Total的挖空计算可观察对来扩展实体。该函数遍历breeze可观察数组FactValues并添加值。我一直在捣乱这个代码的不同版本无济于事。任何人都可以给我一个关于这段代码有什么问题的提示吗?
答案 0 :(得分:1)
<强>更新强>
我们无法获取上一篇文章中发布的代码。我们最终能够通过使用微风自定义绑定来克服这个问题。这是代码:
ko.bindingHandlers.getFyTotal = {
update: function (element, valueAccessor) {
var sum = 0;
var fact = valueAccessor();
if (fact.FactValues()) {
fact.FactValues().forEach(function (fv) {
sum += parseFloat(fv.Value());
});
}
$(element).html(sum);
}
};
然后通过以下方式在HTML代码中引用自定义绑定:
<td data-bind="getFyTotal: $data" />
希望这可以帮助别人。
修订版本
我们已更新上述代码以利用ko.utils函数:
ko.bindingHandlers.getFyTotal = {
update: function (element, valueAccessor) {
var sum = 0;
var fact = valueAccessor();
if (fact.FactValues()) {
ko.utils.arrayForEach(fact.FactValues(), function (fv) {
sum += parseFloat(fv.Value());
});
}
$(element).html(sum);
}
};
答案 1 :(得分:0)
我在Breeze之外建模你的代码并且它正在运行:
http://jsfiddle.net/DazWilkin/yGZ7g/7/
我在构造函数上添加了对FactValues(observableArray)的引用进行了一些小调整,以克服我认为是JavaScript中的循环/此问题。
但是,我没有在Breeze中尝试这个并想做类似的事情。我无法获得类似的功能,最终在我的executeQuery'then'处理过程中创建了总数:
...manager.executeQuery(....).then(function(data) {
...
Fact.Total(FactValues()
.map(function(fv){ return fv.Value(); })
.reduce(function (total,curr) { return total+curr; });
...
}
我今天会尝试回到我的版本,如果我找到更好的解决方案,我会报告回来。