KnockOutJS - 单个视图中的多个视图模型
KnockOutJS - 在单个视图中使用多个ViewModels的原因是因为在一个非常大的项目中有许多ViewModels,需要在单个视图中使用。解决方法是创建多个JavaScript文件来分别为不同的容器创建ViewModels,并在一个公共的JavaScript文件中将这些ViewModels注册为独立的ViewModels。然后使用KnockoutJS的applyBindings方法将ViewModels绑定到相应的容器上。这样可以在不同的div中添加任意数量的ViewModels,但是要确保不在已注册的div内部创建独立的ViewModels。这种解决方法可以解决在复杂的用户界面中生成大量表单的需求,并且可以根据用户输入的条件和收集到的数据来动态改变表单。与其他解决方法相比,这种方法没有任何限制。
在使用KnockOutJS时,有时需要在同一个页面上使用多个ViewModel。解决这个问题的一个简单方法是创建一个包含其他ViewModel数组(或属性列表)的主ViewModel。
masterVM = { vmA : new VmA(), vmB : new VmB(), vmC : new VmC(), }
然后,如果需要的话,主ViewModel还可以有其他属性,用于页面本身。在这种情况下,ViewModel之间的通信将不是困难的,因为可以通过主ViewModel进行中继,或者可以在绑定中使用`$parent` / `$root`,或者其他自定义选项。
那么我可以这样做吗:`data-bind="text: masterVM.vmA"`,我想我仍然可以将`ko.applyBindings`与附加的DOM元素一起使用。我假设这也意味着我可以这样做:`data-bind="$parent.masterVm"`?
您可以使用`with:`绑定,这样您就不需要重复自己了。
是的,如果绑定到主ViewModel,您可以这样做。当您进入子ViewModel时,您还可以使用“with”绑定来避免使用点语法。
在这里更好地解释了这个问题:stackoverflow.com/questions/7342814/…
很棒的问题,而且这个方法的工作原理证明了KnockOutJS是多么棒。
我认为这个答案提供了最灵活的解决方案,因为它允许您从同一个作用域内访问各种ViewModel。使用其他常见方法时,ViewModels不能重叠,这可能会导致其他问题。
我认为这种方法非常受限制...在我的情况下,我正在使用ASP.Net MVC4,这并没有帮助,因为将有拥有自己ViewModel的部分视图,而且部分/内容部分不应相互干扰,由于条件渲染,使用这种方法将非常困难。
使用``将有助于解决多个ViewModel和部分视图部分的问题。了解更多信息,请参阅knockmeout.net/2012/05/quick-tip-skip-binding.html。
KnockoutJS现在支持多个模型绑定。ko.applyBindings()方法接受一个可选参数,即要激活绑定的元素及其后代元素。
例如:
ko.applyBindings(myViewModel, document.getElementById('someElementId'))
这将限制激活绑定的范围为ID为someElementId的元素及其后代元素。
有关更多详细信息,请参见文档。
如果您希望使用jQuery选择器,您需要添加[0]来指定一个实际的DOM元素(而不是jQuery对象),如下所示:ko.applyBindings(myViewModel, $('#someElementId')[0])
这应该是可接受的答案。您仍然可以像当前接受的答案一样使用一个主对象,然后将各个视图模型绑定到页面上相应的元素上。这样可以节省性能,并限制数据绑定所需的范围。
使用这种方法,是否可以让视图模型彼此通信?例如,我有TaskVM和NoteVM。Task可以有Notes。因此,我的TaskVM必须具有一个observableArray,即notes,其类型为TaskVM。您可以分享一个类似的示例吗?
最好创建一个新的问题来询问视图模型之间的通信。