淘汰赛'点击'绑定不起作用

时间:2016-02-22 21:35:59

标签: javascript knockout.js

我正在尝试将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");
    }

};

点击列表名称后我没有收到任何错误,但控制台没有记录任何内容。

我认为我没有正确使用上下文,但无法在此处找出确切的问题。任何帮助将不胜感激。

2 个答案:

答案 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内的divcurrentCatforeach提供了另一层次的上下文。 $parent不引用对象的父级,而是引用此上下文之外的上下文。您可以使用$parents[1]

当您说$parent.catNames时,您只在with上下文中,因此它确实引用catNames中的ViewModel,因为没有其他封闭的上下文。但是,如果你说$parent.updateCurrent,那么你就会跳出foreach上下文,直到with上下文。你想再跳一次。