我正在尝试将click事件绑定到列表项。当我点击下面的列表项时,它应该启动javascript中的updateCurrent
函数,但它没有做任何事情。
注意:当我调用函数并且$parent.updateCurrent
函数位于currentCat
上下文中时,我使用了updateCurrent
,因为我在ViewModel
上下文中。
HTML:
<div id="wrap" data-bind="with: currentCat">
<div id="names">
<ul data-bind="foreach: $parent.catNames">
<!--Here, clicking on name doesn't fire updateCurrent-->
<li data-bind="text: $data, click: $parent.updateCurrent"></li>
</ul>
</div>
</div>
JS:
var viewModel = function() {
var self = this;
this.catNames = ko.observableArray([]);
this.catList = ko.observableArray([]);
//cats is defined as a simple array of objects, having name
cats.forEach(function(catObject) {
self.catList.push(new cat(catObject));
self.catNames.push(catObject.name);
});
//initially, set the currentCat to first cat
this.currentCat = ko.observable(this.catList()[0]);
//should run when the user click on the cat name in the list
this.updateCurrent = function() {
console.log("hello");
}
};
点击列表名称后我没有收到任何错误,但控制台没有记录任何内容。
我认为我没有正确使用上下文,但无法在此处找出确切的问题。任何帮助将不胜感激。
答案 0 :(得分:4)
当您说$ parent.catNames时,您指的是ViewModel,因为它是层次结构中直接父级的拥有属性。使用foreach绑定,您处于一个新的环境中;因此,在$ parent.updateCurrent中,层次结构中的直接父级成为catNames数组中的项目。
你可以在这种情况下使用$ root,正如Viktor所提到的那样,但实现此功能的最安全和正确的方法是一次爬一层,以获得$ parents [1]。
$ parent等于$ parents [0],这是catNames之一。 $ parents [1]将引用ViewModel。
为什么不使用$ root?
Knockout将使您的DOM和绑定环境更加深入,而不是很明显。在模板绑定中,$ root上下文可能引用甚至在HTML模板中的对象!
<div data-bind="template: { name: 'sample', data: catNames }"></div>
<script type='text/html' id='sample'>
<!-- ko foreach: $data -->
<span data-bind="text: 'Cat ' + $index + ' of ' + $parents[0].length"></span>
Returns "Cat 1 of 10"
<!-- /ko -->
<!-- ko foreach: $data -->
<span data-bind="text: 'Cat ' + $index + ' of ' + $root.length"></span>
Return "Cat 1 of undefined" because ViewModel has no length property!
<!-- /ko -->
</script>
绑定上下文文档:http://knockoutjs.com/documentation/binding-context.html
答案 1 :(得分:0)
你在两个层面的上下文中。 with
绑定表示$data
内的div
为currentCat
。 foreach
提供了另一层次的上下文。 $parent
不引用对象的父级,而是引用此上下文之外的上下文。您可以使用$parents[1]
。
当您说$parent.catNames
时,您只在with
上下文中,因此它确实引用catNames
中的ViewModel
,因为没有其他封闭的上下文。但是,如果你说$parent.updateCurrent
,那么你就会跳出foreach
上下文,直到with
上下文。你想再跳一次。