当我更新我的viewmodel时,我遇到了这个奇怪的问题...基本上每次更新时,似乎每个observable都会随机包含这些数据:
function observable() {
if (arguments.length > 0) {
// Write
// Ignore writes if the value hasn't changed
if ((!observable['equalityComparer']) || !observable['equalityComparer'](_latestValue, arguments[0])) {
observable.valueWillMutate();
_latestValue = arguments[0];
observable.valueHasMutated();
}
return this; // Permits chained assignments
} else {
// Read
ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation
return _latestValue;
}
}
我一直在使用KnockoutJS,我从来没有见过这样的东西。我的猜测是它与我的模板绑定有关,但我真的不确定。我要深入研究它,但我想我会在这里发布它,以防其他人遇到这个问题,或者有解决方案。就像我说的那样,它不会一直发生,只是偶尔发生。
////更多信息////
所以Matt在下面引用了这个问题(http://stackoverflow.com/questions/9763211/option-text-becomes-a-function-string-after-updated-with-fromjs),这大致是同一个问题。唯一的区别是我在这样的样式中使用本机模板绑定:
<div data-bind="template: {name: 'issueTemplate', data: incidents}"></div>
<script id="dashboardIssueTemplate" type="text/html">
<!--ko foreach: $data-->
<div data-bind="text: title"></div>
</script>
当我将observableArray传递给模板绑定器时,我假设KnockoutJS自行处理解包。我知道在这个例子中我不能说“title()”,因为那不存在。我应该用像$ root.title()这样的命令绑定吗?
////更多信息////
由于在一个页面上有两个“applyBindings”,似乎会出现此问题。我的应用程序包含一个外部窗口小部件,它在运行时将它的DOM添加到主机页面DOM。该小部件使用ko.applyBindings(vm,ROOTNODE)语法,该语法应该允许主机页面运行它自己的ko.applyBindings(hostVm)。
事实上,确实如此,每次刷新都能正常工作。但问题是主机页面在没有刷新的情况下执行viewModel更新。不知何故,UI呈现在每个数据绑定节点上吐出这个内部函数。我通过KnockoutJS调试并实际确认viewModel和rootNode是正确的......实际绑定之外的东西正在接管。
答案 0 :(得分:1)
这与附加到模板中数据对象的“()”有关。我发现在第一次渲染(页面加载)期间编写模板如下:
<div data-bind="template: {name: 'issueTemplate', data: incidents}"></div>
<script id="dashboardIssueTemplate" type="text/html">
<div data-bind="text: title"></div>
</script>
工作得很好。但是,一旦在observableArray上运行更新,我的“title”对象就变成了该函数。如果我使用这种风格编写模板:
<div data-bind="text: title()"></div>
它似乎适用于每次更新。
我不确定为什么这是解决方案。从它的外观来看,传递给Knockout活页夹的数据对象在页面加载和更新上完全相同。我会将此作为答案发布,但在我理解为什么会发生这种情况之前,我不会将其标记为答案。