以下代码适用于早期版本的KO(2.x),但在新版本(3.x)中失败。单击超链接应在视图模型中调用函数showSectionName。我得到的错误是:
Uncaught TypeError: Cannot read property '$data' of undefined
检查我的小提琴here
检查与KO 2.x here
一起使用的非常相似的版本我的HTML:
<div style="width:200px">
<ul class="nav nav-pills nav-stacked" data-bind=" template: { name: 'itemTmpl', foreach: sections, templateOptions : { select: showSectionName }}"></ul>
<script id="itemTmpl" type="text/html">
<li role="presentation" data-bind="bootstrapHyperlink: { action: $data.select, params: [ $data ] }">
</li>
</script>
</div>
我的剧本:
$(function () {
ko.bindingHandlers.bootstrapHyperlink = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var elt = "<a href='#'>" + viewModel.name + "</a>";
$(element).append(elt);
var options = valueAccessor();
var newValueAccessor = function () {
return function () {
options.actions.apply(context, options.params);
};
};
ko.bindingHandlers.click.init(element, newValueAccessor, allBindings, bindingContext);
},
}
Section = function (id, name) {
var self = this;
self.id = id,
self.name = name
};
function viewModel() {
var self = this;
self.sections = ko.observableArray(
[
new Section(10, "Section 1"),
new Section(20, "Section 2"),
new Section(30, "Section 3")
])
self.showSectionName = function (item) {
alert("You clicked the section " + item.name);
}
}
ko.applyBindings(new viewModel());
});
答案 0 :(得分:2)
基本上我认为您遇到的问题是templateOptions
在模板绑定文档中没有提及它,这个问题看起来有点https://github.com/knockout/knockout/issues/365
我更新了小提琴https://jsfiddle.net/c2fe9bs8/4/
要避免使用templateOptions,您可以使用$parent
特殊属性来访问您的viewModel,如下所示:
<li role="presentation" data-bind="
bootstrapHyperlink: { action: $parent.showSectionName, params: [ $data ] }
"></li>
这是一个意见问题,但是由于您已经在使用jQuery并且如果删除了节点,则删除事件处理程序也可能更容易绑定到click事件:
ko.bindingHandlers.bootstrapHyperlink = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var options = valueAccessor();
var link = $('<a href="#">' + viewModel.name + '</a>');
$(element).append(link);
link.on('click', function () {
options.action.apply(bindingContext, options.params);
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
link.off('click');
});
}
}
答案 1 :(得分:0)
脚本:
<script type="text/javascript">
$(function () {
ko.bindingHandlers.bootstrapHyperlink = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var elt = "<a href='#'>" + viewModel.name + "<span class='badge'>" + viewModel.id + "</span></a>";
$(element).append(elt);
},
}
Section = function (id, name) {
var self = this;
self.id = id,
self.name = name
};
function viewModel() {
var self = this;
self.sections = ko.observableArray(
[
new Section(10, "Section 1"),
new Section(20, "Section 2"),
new Section(30, "Section 3")
])
self.showSectionName = function (item) {
alert("You clicked the section " + item.name);
}
}
ko.applyBindings(new viewModel());
});
</script>
HTML:
<li role="presentation" data-bind="bootstrapHyperlink: { action: $index.select, params: [ $index ] }, click:$root.showSectionName">
</li>
</ul>
</div>