我将来自服务器的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();
});
}
我还创建了this jsfiddle来演示。
答案 0 :(得分:3)
在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));
}
答案 1 :(得分:2)
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
文档中了解有关managing this的详情。