我遇到了KnockoutJS的一个问题,数据绑定似乎没有按预期更新。
在我的视图模型中,我有一个对象数组,其中包含一个Enabled属性,我将其初始化为True,并将该属性绑定到一个带有单击处理程序CheckItems的复选框上以启用该属性:
self.Answers(data.filter(function (step) {
if (step.Type == 0) {
step.Enabled = true;
return true;
}
else {
return false;
}
}));
...
<ul data-bind="foreach: $root.Answers">
<input type="checkbox" data-bind="click: $root.CheckItems, ..., enable: Enabled>
</ul>
一切都运行得很好,直到CheckItems处理程序运行并且我尝试将Enabled属性设置为false:
self.CheckItems = function (step) {
...
self.Answers().forEach(function (option) {
<call my handler>.done(function (data) {
option.Enabled = data;
}
);
});
// EDIT: added valueHasMutated() call here
self.Answers.valueHasMutated();
return true;
}
当我点击返回真时,我可以检查自我。Answers()对象,它显示应禁用的答案的Enabled = false(正确),但一旦我们成为处理程序,所有复选框都不会被禁用,并单击任何其他存在的复选框,然后通过处理程序显示Enabled属性似乎已被重置为True。我进行了三次检查,并确保在单击复选框之间的代码中的任何位置都没有触及Enabled属性的其他内容。
绑定本身似乎也在工作,因为当我将初始的Enable设置切换为false时,所有的复选框都被禁用。
我正在修改self.Answers数组以及脚本中的其他地方,这些地方都很好,当修改完成后,它会进入knockout-latest.debug.js,并在notifySubscribers函数中进行适当的更新。也许knockout中输入字段的click事件有什么特别之处?
有什么想法吗?对Knockout总体来说还是相当新的,但我认为这就是全部的要点,我可以更新Answers()可观察数组中的属性,它将在相应的UI中更新。
Edit:根据评论,我在编辑后尝试调用valueHasMutated(),但它仍然无法正确更新。
Edit 2:尝试制作self.Answers数组的副本,执行处理程序调用以更新Enabled,然后使用self.Answers(newAnswers)进行设置,但结果相同。
1条答案
按热度按时间sqyvllje1#
我被告知发生此问题的原因是CurrentAnswers中的对象属性()也是不可观测的,因为阵法本身没有变化,所以击倒并没有意识到它需要重新绑定任何东西,这就是为什么调用valueHasMutated()没有更改任何内容,因为CheckItems前后的数组看起来完全相同()从数组的Angular 来看(也是为什么用数组的副本更新不起作用的原因,同样的问题)。当将CurrentAnswers()设置为一个空数组(self.CurrentAnswers([])),然后将其设置为更新后的值时,事情发生了正确的变化,因为KO识别出了实际的数组变化。
我最终使用的解决方案是利用ko.mapping.fromJS()方法用具有可观察属性的对象填充CurrentAnswers()。在HTML和JS中进行了一些语法更改以正确引用新的可观察属性之后,一切都正常工作。