6

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

  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可观察的。它说Navigate是 undefined 。无法解析. Same goes forselectedFolderId`。

知道为什么会这样吗?

4

1 回答 1

14

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

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

因此,如果您想访问您需要使用navigate的方法,或访问您的“根”视图模型(您可以阅读有关绑定上下文的更多信息):chosenFolderId$parent$root

<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的复杂函数,则应将函数用作视图模型,而不是可以存储的对象文字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 将为您传递当前项目。

这是一个有效的 JSFiddle

如果您想使用对象文字作为您的视图模型来执行此操作,则JSFiddle演示了该方法。

但是,您应该知道两种视图模型创建方法的优势和劣势。这个SO问题很好地总结了它:Difference between knockout View Models declared as object literals vs functions

于 2012-12-19T06:02:05.047 回答