我正在尝试对 ASP.NET MVC 4 应用程序进行一些增强,该应用程序在浏览器中大量使用了 knockout.js 和 MVVM 模式。我正在选择淘汰赛,我真的很喜欢它,但我设法引起了一个意想不到的错误。
我有一个表,并且正在使用数据绑定属性中的 foreach 外观,该属性循环通过淘汰视图模型并创建行。
在视图模型中,我添加了更多属性来支持一个新的页脚行,该行合计表中的数字列。
不幸的是,当我回发到控制器时,我在视图模型中添加的属性导致一行被删除。我怀疑我使用了错误的淘汰赛结构来添加这些总数......
...这是在视图模型中...
self.BudgetTotal = ko.computed(function () {
var total = 0;
//The problem is this loop! It's messing with the Phases observable array and it's all magic behind the scenes and I can't see what's going wrong
for (i = 0; i < self.Phases().length; i++)
total = parseFloat(total) + parseFloat(self.Phases()[i].Total());
return format_number(total, 2);
});
这是表格:
<table class="table table-bordered table-compact">
<thead>
<tr>
<th></th>
<th>Phase</th>
<th>Name</th>
<th>Phase Manager</th>
<th>Labor</th>
<th>Expense</th>
<th>Subs</th>
<th>Total</th>
</tr>
</thead>
<tbody data-bind="template: {foreach: Phases.sort(function (l, r) { return l.Code() > r.Code() ? 1 : -1 }) }">
<tr>
<td><input type="checkbox" data-bind="checked: IsSelected, click:SelectionChanged"/></td>
<td class="phasecode" data-bind="text: Code"></td>
<td><input type="text" data-bind="value: Name, visible: IsAdditional" class="input-small phaseName" maxlength = "35"/><span data-bind="text: Name, visible: !IsAdditional()"></span></td>
<td><input type="hidden" id="CompanyCode" data-bind="value: Company().Code" /><input type="text" class="PhaseManagerTypeahead phaseManager" data-bind="value: PhaseManager().CodeName, enable: IsSelected" autocomplete="off"/></td>
<td>
<nobr><input class="span1" id="inputIcon" type="text" data-bind="value: Labor, enable: IsSelected" style="text-align:right" onblur="checkDecimal(this)" maxlength = "20"/></nobr>
</td>
<td>
<nobr><input class="span1" id="inputIcon" type="text" data-bind="value: Expenses, enable: IsSelected" style="text-align:right" onblur="checkDecimal(this)" maxlength = "20"/></nobr>
</td>
<td>
<nobr><input class="span1" id="inputIcon" type="text" data-bind="value: Subcontractor, enable: IsSelected" style="text-align:right" onblur="checkDecimal(this)" maxlength = "20"/></nobr>
</td>
<td data-bind="text: Total" style="min-width:80px; text-align:right"></td>
</tr>
</tbody>
<tfoot class="hideFromPrinter">
<tr>
<td colspan="8"><a href="javascript:void(0);" data-bind='click: viewModel.addAdditionalPhase'>Add Additional Phase...</a></td>
</tr>
</tfoot>
</table>
我删除了显示总数的页脚行,但发现它与错误无关。如果我把上面的淘汰代码注释掉,这个 bug 就消失了。当我取消注释时,错误又回来了。
解决方案是使用实用函数 arrayForEach 迭代可观察数组。
self.BudgetTotal = ko.computed(function () {
var total = 0;
ko.utils.arrayForEach(self.Phases, function (item) {
var value = parseFloat(item.Total());
if(!isNaN(value))
total += value;
}
);
return total.toFixed(2);
});