【问题标题】:Access child view model in Knockout在 Knockout 中访问子视图模型
【发布时间】:2015-10-30 20:50:56
【问题描述】:

有没有办法从其父视图模型中访问子视图模型?我的用例是我有一些自定义的淘汰赛组件。我在单独的文件中为每个组件都有一个基本定义。我希望能够根据网站的哪个部分使用不同的方式来定制它们。这可能吗?有很多关于如何从孩子访问父视图模型的文档,但不是相反。

所以理想情况下,我希望能够做以下事情:

parentViewModel.someChildModel.someProperty(someValue);

【问题讨论】:

    标签: knockout.js components viewmodel parent children


    【解决方案1】:

    我发现这样做的方法是让父虚拟机构造子虚拟机,然后将子虚拟机作为参数注入子组件,方法是将子虚拟机定义为:

    ko.components.register("child", {
        viewModel: {
            createViewModel: function(params, componentInfo) {
                return params.viewModel;
            }
        },
        template: {
            element: 'child-template'
        }
    });
    

    子组件没有定义特定的构造函数或实例,而是使用createViewModel 函数,该函数使用“viewModel”组件参数作为视图模型。 (为了安全起见,可以在这里检查是否提供了视图模型以及它是否是预期的类)

    然后,父虚拟机可以简单地构造子虚拟机,因此可以完全访问它们及其属性。 (例如self.child = new ChildVM()

    最后,模板必须将 ViewModel 实际提供给子组件:

    <child params="viewModel: child"></child>
    

    它涉及一些样板文件,但这是我发现的父母与孩子之间交流的最佳方式。

    完整示例:

    function ParentVM() {
        var self = this;    
    
        self.message = ko.observable();
    
        var callback = function (message) {
            self.message(message);
        }
    
        self.children = ["foo", "bar"].map(function (text) {
            return new ChildVM(text, callback);
        });
    }
    
    function ChildVM(text, callback) {
        var self = this;
    
        self.text = text;
    
        self.onClick = function () {
            callback(text + " clicked");   
        }
    }
    
    vm = {};
    
    ko.components.register("parent", {
        viewModel: ParentVM,
        template: {
            element: 'parent-template'
        }
    });
    
    ko.components.register("child", {
        viewModel: {
            createViewModel: function(params, componentInfo) {
                return params.viewModel;
            }
        },
        template: {
            element: 'child-template'
        }
    });
    
    ko.applyBindings(vm);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    <parent></parent>
    
    <template id='parent-template'>
      <!-- ko foreach: children -->
      <child params="viewModel: $data"></child>
      <br />
      <!-- /ko -->
      <span data-bind="text: message"></span>
    </template>
    
    <template id='child-template'>
      <span data-bind="
            text: text,
            click: onClick
        "></span>
    </template>

    【讨论】:

    • 这很有趣!但是,我无法在代码 sn-p 中触发警报?
    • 哦,显然代码 sn-ps 无法触发警报。现在不使用警报已修复;所以它应该是功能性的。
    猜你喜欢
    • 2012-08-04
    • 2013-09-16
    • 2013-01-03
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 2014-03-06
    相关资源
    最近更新 更多