敲击绑定未定义为单击

时间:2012-12-19 04:36:53

标签: knockout.js

我有一个视图模型必须附加到<li>标记的点击事件。这是viewmodel和markup

  var viewModel =
    {
        Folders: ['Inbox', 'Archive', 'Sent', 'Spam'],
        SelectedFolder: ko.observable('Inbox'),
        chosenFolderId: ko.observable(),
        navigate: function () {
            self.chosenFolderId(folder);               
        }
    };
ko.applyBindings(viewModel);

标记是

   <ul class="nav nav-list bs-docs-sidenav affix" data-bind="foreach:Folders">
                @*<li data-bind="css:{active: $data == chosenFolderId() }">*@
                <li>
                    <a href="#" data-bind="click:navigate">                      
                        <!-- ko text: $data -->
                        <!-- /ko -->
                        <i class="icon-chevron-right"></i>
                    </a>
                </li>                   
            </ul>

问题出在这一行

<a href="#" data-bind="click:navigate"> 

<li data-bind="css:{active: $data == chosenFolderId() }">

上述两行都没有分别附加到Navigate函数和chosenFolderId observable。它说Navigate未定义。无法解析. Same goes for selectedFolderId`。

知道为什么会这样吗?

1 个答案:

答案 0 :(得分:12)

您当前的方法存在一些问题:

当您在data-bind="foreach:Folders"内使用foreach binding例如ul时,“当前上下文”将成为您文件夹集合中的项目。

因此,如果您想要访问navigatechosenFolderId方法,则需要使用$parent$root来访问您的“root”视图模型(您可以详细了解binding context):

<ul class="nav nav-list bs-docs-sidenav affix" data-bind="foreach:Folders">
    <li data-bind="css:{active: $data == $parent.chosenFolderId() }">
        <a href="#" data-bind="click: $parent.navigate">                      
            <!-- ko text: $data -->
            <!-- /ko -->
            <i class="icon-chevron-right"></i>
        </a>
    </li>                   
</ul>​

您的视图模型中也存在一些问题。如果你有navigate之类的复杂函数试图使用self,你应该使用一个函数作为viewmodel而不是一个可以存储this的对象文字:

var viewModel = function() {
    var self = this;
    self.Folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
    self.SelectedFolder = ko.observable('Inbox');
    self.chosenFolderId = ko.observable();
    self.navigate = function(folder) {
        self.chosenFolderId(folder);
    }
};
ko.applyBindings(new viewModel());​

请注意:您的navigate函数需要folder参数才能使其正常工作,Knockout会为您传递当前项目。

这是working JSFiddle

如果你想用一个对象文字作为你的视图模型,那么JSFiddle就证明了这种方法。

但是你应该知道两种视图模型创建方法的强度和周长。这个问题总结得很好:Difference between knockout View Models declared as object literals vs functions