KnockOutJS -在一个视图中有多个视图模型

我认为我的应用程序现在变得非常大,大到无法用一个ViewModel处理每个View。

所以我想知道创建多个viewmodel并将它们全部加载到单个视图中有多难。需要注意的是,我还需要能够将X视图模型数据传递到Y视图模型数据中,以便各个viewmodel能够相互通信,或至少能够相互了解。

例如,我有一个<select>下拉菜单,这个下拉菜单有一个选择状态,允许我将<select>中所选项的ID传递给另一个单独的ViewModel....中的Ajax调用

任何关于在一个视图中处理多个视图模型的观点都值得赞赏:)

85668 次浏览

如果它们都需要在同一个页面上,一个简单的方法是有一个包含其他视图模型的数组(或属性列表)的主视图模型。

masterVM = {
vmA : new VmA(),
vmB : new VmB(),
vmC : new VmC(),
}

然后,如果需要,你的masterVM可以为页面本身拥有其他属性。在这种情况下,视图模型之间的通信并不困难,因为你可以通过masterVM进行中继,或者你可以在绑定中使用$parent / $root,或者其他一些自定义选项。

检查MultiModels插件Knockout JS - https://github.com/sergun/Knockout-MultiModels

Knockout现在支持多模型绑定。ko.applyBindings()方法接受一个可选参数——绑定将被激活的元素及其子代。

例如:

ko.applyBindings(myViewModel, document.getElementById('someElementId'))

这将激活限制到ID为someElementId的元素及其后代。

更多细节参见文档

这是我在单一视图中完成大量ViewModels的大型项目后的答案。

Html视图

    <!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创建了2个视图模型。

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");


}

然后这两个视图模型在datfunction .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添加任意数量的视图模型。但是请确保不要在注册div中为一个div创建单独的视图模型。

我们使用组件来实现这一点。(http://knockoutjs.com/documentation/component-overview.html)

例如,我们有这个正在开发的组件库:https://github.com/EDMdesigner/knobjs

如果深入研究代码,您会发现,例如,我们在几个地方重用了旋钮按钮组件。