如何在循环中创建ko.computed变量,以便在重新计算时,计算函数内部循环变量的值与首次定义计算函数时的变量相同?
这是我期望闭包工作的方式,但是:
http://jsbin.com/dileju/6/edit?html,js,output (在输入框中输入1以外的数字,然后按返回)
重新计算时使用的值是循环最后一次迭代中变量的值。
答案 0 :(得分:1)
摆脱for
循环,它搞乱了(因为关闭的方式如同@Andrew在评论中正确指出的那样)。
var ViewModel = function() {
var self = this;
self.multipler = ko.observable(1);
self.things = ko.observableArray();
self.fakeServerData = [
{ id: 1, properties: { name: '1', val: 1 }},
{ id: 2, properties: { name: '2', val: 2 }},
{ id: 3, properties: { name: '3', val: 3 }}
];
ko.utils.arrayForEach(self.fakeServerData, function (item) {
var props = item.properties,
multi = +self.multipler();
props.computed = ko.pureComputed(function () {
return multi * props.val;
});
});
};
ko.applyBindings(new ViewModel());
经验法则是:Don't make functions in a loop。如果必须创建函数,请不要使用循环。
避免循环的方法是使用本机数组函数(Array.prototype.forEach
)或来自各种库的等价函数,例如knockout自己的ko.utils.arrayForEach()
,jQuery' s {{ 1}}或下划线/ lodash' s $.each
和其他人。
答案 1 :(得分:1)
对于你正在做的事情,你并不需要为数组中的每个元素计算。您可以使用函数并将其传递给当前元素。函数在绑定中工作正常。 Knockout将跟踪其可观察的依赖关系。
所以你的绑定将是
<span data-bind="text: $parent.thingy($data)"></span>
该功能将是:
self.thingy = function (data) {
var mult = parseInt(self.multipler());
return mult * data.val;
};
你可以建立你的东西列表,如:
for (var i = 0; i < self.fakeServerData.length; i++) {
var props = self.fakeServerData[i].properties;
self.things.push(props);
}