我有一个视图模型必须附加到<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`。
知道为什么会这样吗?
答案 0 :(得分:12)
您当前的方法存在一些问题:
当您在data-bind="foreach:Folders"
内使用foreach binding例如ul
时,“当前上下文”将成为您文件夹集合中的项目。
因此,如果您想要访问navigate
或chosenFolderId
方法,则需要使用$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会为您传递当前项目。
如果你想用一个对象文字作为你的视图模型,那么JSFiddle就证明了这种方法。
但是你应该知道两种视图模型创建方法的强度和周长。这个问题总结得很好:Difference between knockout View Models declared as object literals vs functions