[英]Looping through array to add ko.computed to each object
我将来自服务器的viewmodel作为JSON传递,然后在调用ko.applyBindings()
之前向viewmodel添加一些函数和observable。
我的问题是我想循环遍历一个对象数组,并在每个对象上添加一个计算的observable。 但是,所有计算的observable似乎都绑定到我的数组中的最后一个对象。
这是循环:
for (var i = 0; i < viewModel.Records().length; i++)
{
var record = viewModel.Records()[i];
viewModel.Records()[i].CachedMonthlyAmount = ko.computed(function () {
var frequencyType = viewModel.GetFrequencyTypeByID(record.SelectedFrequencyTypeID());
return frequencyType.MonthlyCalculationFactor() * record.Amount();
});
}
我也创建了这个jsfiddle来演示。
当你在for循环中使用变量时,你需要创建一个closure
(例如,使用立即调用的函数表达式IIFE ),这样你就可以将每个计算函数中的record
变量绑定到计算函数之外的单独的不变量值。
你只需要做:
for (var i = 0; i < viewModel.Records().length; i++)
{
var record = viewModel.Records()[i];
(function(record){
record.CachedMonthlyAmount = ko.computed(function () {
var frequencyType = viewModel.GetFrequencyTypeByID(record.SelectedFrequencyTypeID());
return frequencyType.MonthlyCalculationFactor() * record.Amount();
});
}(record));
}
ko.computed
的第二个参数定义了将用于在计算的回调函数中this
进行求值的目标对象。 因此,您可以将record
作为第二个参数传递,这将导致正确的计算评估。
for (var i = 0; i < viewModel.Records().length; i++) {
var record = viewModel.Records()[i];
viewModel.Records()[i].CachedMonthlyAmount = ko.computed(function () {
var frequencyType = viewModel.GetFrequencyTypeByID(this.SelectedFrequencyTypeID());
return frequencyType.MonthlyCalculationFactor() * this.Amount();
}, record);
}
阅读有关从ko.computed
文档管理此内容的更多信息。
更新小提琴: http : //jsfiddle.net/952pfm61/4/
更简单的解决方案是在Ko中使用来自Utility函数的 arrayForEach
修改过的一段代码:
ko.utils.arrayForEach(viewModel.Records(),function(item){
item.CachedMonthlyAmount = ko.computed(function () {
var frequencyType = viewModel.GetFrequencyTypeByID(item.SelectedFrequencyTypeID());
return frequencyType.MonthlyCalculationFactor() * item.Amount();
});
});
使用基于index
的值分配我相信那些日子已经过去了(至多)。 至于ko
,因为你试图通过computed
创建一个依赖(基于索引的赋值),这是不可取的。 通过使用计算函数的2nd parameter
确实可能。
在这里工作样本
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.