我认为我的应用程序现在变得非常大,太大而无法使用单个ViewModel处理每个View。
所以我想知道创建多个ViewModel并将它们全部加载到一个View中会有多困难。需要注意的是,我还需要能够将 X ViewModel 数据传递到 Y ViewModel 数据,以便各个ViewModel需要能够相互通信或者至少是彼此意识到了。
例如我有一个<select>
下拉列表,选择下拉列表具有一个选定状态,允许我将<select>
中所选项目的ID传递给另一个ViewModel中的另一个Ajax调用....
在单个视图中处理众多ViewModel的任何要点都表示赞赏:)
答案 0 :(得分:283)
Knockout现在支持多种模型绑定。 ko.applyBindings()
方法采用可选参数 - 要激活绑定的元素及其后代。
例如:
ko.applyBindings(myViewModel, document.getElementById('someElementId'))
这会将激活限制为ID为someElementId
及其后代的元素。
有关详细信息,请参阅documentation。
答案 1 :(得分:147)
如果它们都需要在同一页面上,一个简单的方法是使用包含其他视图模型的数组(或属性列表)的主视图模型。
masterVM = {
vmA : new VmA(),
vmB : new VmB(),
vmC : new VmC(),
}
然后,如果需要,您的masterVM
可以为页面本身提供其他属性。在这种情况下,视图模型之间的通信并不困难,因为您可以通过masterVM
进行中继,或者您可以在绑定或其他一些自定义选项中使用$parent
/ $root
。< / p>
答案 2 :(得分:21)
这是我在单视图中完成包含大量ViewModel的大型项目后的答案。
Html View
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div id="container1">
<ul>
<li >Container1 item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
</div>
<div id="container2">
<ul>
<li >Container2 item</li>
<!-- ko foreach: myItems -->
<li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->
</ul>
</div>
<script src="js/jquery-1.11.1.js"></script>
<script src="js/knockout-3.0.0.js"></script>
<script src="js/DataFunction.js"></script>
<script src="js/Container1ViewModel.js"></script>
<script src="js/Container2ViewModel.js"></script>
</body>
</html>
对于这个视图,我在两个单独的javascript文件中为id = container1和id = container2创建了两个视图模型。
Container1ViewModel.js
function Container1ViewModel()
{
var self = this;
self.myItems = ko.observableArray();
self.myItems.push("ABC");
self.myItems.push("CDE");
}
Container2ViewModel.js
function Container2ViewModel() {
var self = this;
self.myItems = ko.observableArray();
self.myItems.push("XYZ");
self.myItems.push("PQR");
}
然后在这两个视图模型在DataFunction.js中注册为单独的视图模型
var container1VM;
var container2VM;
$(document).ready(function() {
if ($.isEmptyObject(container1VM)) {
container1VM = new Container1ViewModel();
ko.applyBindings(container1VM, document.getElementById("container1"));
}
if ($.isEmptyObject(container2VM)) {
container2VM = new Container2ViewModel();
ko.applyBindings(container2VM, document.getElementById("container2"));
}
});
像这样你可以为不同的div添加任意数量的viewmodel。但请确保不要为已注册的div内的div创建单独的视图模型。
答案 3 :(得分:3)
检查Knockout JS的MultiModels插件 - https://github.com/sergun/Knockout-MultiModels
答案 4 :(得分:0)
我们使用组件来实现这一目标。 (http://knockoutjs.com/documentation/component-overview.html)
例如,我们正在开发这个组件库:https://github.com/EDMdesigner/knobjs
如果你深入研究代码,你会看到我们在几个地方重复使用了旋钮按钮组件。