首页 文章

KnockOutJS - 单个视图中的多个ViewModel

提问于
浏览
193

我认为我的应用程序现在变得非常大,太大而无法使用单个ViewModel处理每个View .

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

例如,我有一个 <select> 下拉列表,选择下拉列表具有一个选定状态,允许我将 <select> 中所选项目的ID传递给另一个ViewModel中的另一个Ajax调用....

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

5 回答

  • 20

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

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

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

  • 0

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

    例如:

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

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

    有关详细信息,请参阅documentation .

  • 146

    这是我在单视图中完成包含大量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添加任意数量的viewmodel . 但请确保不要为已注册的div内的div创建单独的视图模型 .

  • 3

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

  • 282

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

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

    如果您深入研究代码,您将看到例如我们在几个地方重复使用旋钮按钮组件 .

相关问题