202

我在想我的应用程序现在变得非常大,太大而无法使用单个 ViewModel 处理每个视图。

所以我想知道创建多个 ViewModel 并将它们全部加载到一个 View 中会有多困难。需要注意的是,我还需要能够将X ViewModel数据传递到Y ViewModel数据中,因此各个 ViewModel 需要能够相互通信或至少相互了解。

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

在单个视图中处理多个 ViewModel 的任何要点表示赞赏:)

4

5 回答 5

288

Knockout 现在支持多个模型绑定。该ko.applyBindings()方法采用可选参数 - 将激活绑定的元素及其后代。

例如:

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

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

有关更多详细信息,请参阅文档

于 2012-07-20T02:36:53.973 回答
150

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

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

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

于 2012-02-15T13:59:10.870 回答
24

这是我在完成非常大的项目后的答案,在单个视图中有很多 ViewModel。

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

}

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

于 2014-07-16T13:29:54.610 回答
4

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

于 2012-06-27T16:09:23.737 回答
0

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

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

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

于 2016-06-28T20:15:55.787 回答