在组件绑定中访问root上的方法

时间:2016-05-26 03:53:59

标签: knockout.js

我这里有一些knockoutjs组件的示例代码,其中我有一个需要解决的问题:

<template id="item-list-tmpl">
   <ul data-bind="foreach: MyList">
      <li>
         <span data-bind="text: $data.DisplayText"></span>
         <span data-bind="text: $root.DeleteItem"></span>
      </li>
   </ul>
</template>
ko.components.register('item-list', {
    template: $("#item-list-tmpl").html(),
    viewModel: function (params) {
        self.MyList = params.MyList; // object inside this list { DisplayText: "Sample Text" }
    }
});

我想知道如何访问我的根视图模型上的Delete函数

以下是我使用该组件的方式:

<div data-bind='component:{
            name: "item-list"
            params: { 
               MyList: myVM.MyList 
            }
       }'></div>

以下是MyList所在的主视图模型代码结构:

function MainVM(){
   var self = this;

   self.MyList = ko.observableArray([{ DisplayText: "Sample Text" }]);
   self.Delete = function(value){
       self.MyList.remove(value);
   };
}

我的问题是我似乎无法从列表元素中的主视图模型访问Delete函数。这里有没有人知道发生了什么?

1 个答案:

答案 0 :(得分:1)

但是你想要访问 root 对象上的Delete,因为我不认为它存在。相反,它似乎将出现在根myVM属性上。

因为你MyList: myVM.MyList有效地跳过了一层上下文,所以myVM永远不是真正的上下文,当你访问root时,你总是必须再次引用它。所以像$root.myVM.Delete这样的东西应该有效。或者,您可以通过$parents[]层次结构:

ko.components.register('item-list', {
    template: $("#item-list-tmpl").html(),
    viewModel: function (params) {
        self.MyList = params.MyList; // object inside this list { DisplayText: "Sample Text" }
    }
});

function MainVM(){
   var self = this;
   self.MyList = ko.observableArray([{ DisplayText: "Sample Text" }]);
   self.Delete = function(value){ console.log(value);
       self.MyList.remove(value);
   };
}

ko.applyBindings({myVM: new MainVM()});
pre { background: white; padding: 10px; color: #333; font: 11px consolas; border: 1px solid #ddd; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<template id="item-list-tmpl">
   <ul data-bind="foreach: MyList">
      <li>
         <span data-bind="text: $data.DisplayText"></span>
         <button data-bind="click: $root.myVM.Delete">$root.myVM.Delete</button>
         <button data-bind="click: $parents[1].myVM.Delete">$parents[1].myVM.Delete</button>
      </li>
   </ul>
</template>

<div data-bind='component: { 
  name: "item-list",   
  params: { MyList: myVM.MyList } 
}'></div>

<hr>Debug info: <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>