我有一个非常复杂的jquery模板,我通过knockout.js框架与基于javascript的ViewModel
数据绑定。实际上,我在另一个observableArray
中有ViewModel
个ViewModel
个对象绑定到我的模板。
在我的模板中,我有几个DOM元素,当它们的值发生变化时会触发某些事件。例如,我有一个单选按钮设置,当选择一个值时,它会改变选择列表的绑定(以及启用),这反过来通过改变各种可观察的属性来清除文本框的值(以及启用)在我的界限内ViewModel
。这些触发器有助于为最终用户指导UX流程,并确保根据需要保存或清除某些值。这一切都很好。
...然而
当我从我的数据库中检索初始数据并填充我的ViewModels
时,然后将ViewModels
绑定到模板,触发器会触发它们。但是,我不希望由于触发器触发而清除基础可观察值。因此,我设计的是一种初始设置ViewModel
的{{1}}可观察值为IsInitialData
的方法,我的触发器用它来确定是否清除某些值。但是,我希望在完成模板绑定之后,以及在执行任何用户交互之前,将这些属性设置为true
。
对我来说最有意义的是使用false
回调将afterRender
属性设置为IsInitialData
。这样,我的触发器会在绑定初始数据后正常触发。我的false
回调函数如下所示:
afterRender
有趣的是,即使设置了值,我也可以在上述函数中读取该值。
...然而
一旦我在上面的function resetIsInitialDataAttribute(nodesArray, dataValue) {
alert(dataValue.IsInitialData()); // Displays 'true'
dataValue.IsInitialData(false);
alert(dataValue.IsInitialData()); // Displays 'false'
}
回调函数中设置了值,我的可观察绑定似乎就会中断。为了测试,我在模板中放置了一个div来序列化我的afterRender
,这样我就可以显示所有observableArray
的值:
ViewModel
如果我没有在<div data-bind="text: ko.toJSON(locationsViewModel.locations)"></div>
回调中设置IsInitialData
属性,那么当我修改已绑定到afterRender
可观察属性的DOM元素时,以上div立即显示修改后的值。但是,如果我在回调函数中设置了ViewModel
属性,则上面的div不再在IsInitialData
中显示任何更改的值。
有谁知道为什么在ViewModel
回调函数中设置我的ViewModel
属性会导致问题?在我的初始数据库绑定完成后,是否有另一种方法可以设置afterRender
IsInitialData
属性?我查看了jQuery.tmpl文档中的任何类型的回调,我可以使用它在绑定我的数据后发生,但没有发现任何可用的。
答案 0 :(得分:6)
您的问题基本上是此问题的一个版本:https://github.com/SteveSanderson/knockout/issues/133。还描述了here。
在afterRender
期间,元素实际上还不在DOM中。在刚刚绑定到元素的此代码(或绑定)中设置observable的值将导致重新评估该元素绑定中使用的dependentObservable。它会看到该元素不在DOM中,并认为它应该自行处理。
一个简单的解决方法是在afterRender
中设置您的值,如:
setTimeout(function() { dataValue.IsInitialData(false); }, 0);
这将使当前执行完成,此时元素将在DOM中。