KO 组件内的 foreach 绑定中的 $component 不正确
$component incorrect within foreach binding inside a KO component
JS Fiddle 显示问题:http://jsfiddle.net/davetropeano/58vm9r6g/7/
我有一个呈现可观察数组的自定义组件。列表元素是只读的,我试图支持让用户删除一个元素。
这是模板:
<template id="kv-list">
<input type="text" placeholder="key" data-bind="textInput: k">
<input type="text" placeholder="value" data-bind="textInput: v">
<button data-bind="click: add">Add</button><br>
<table>
<thead>
<tr>
<th data-bind="text: keyHeading"></th>
<th data-bind="text: valueHeading"></th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: k"></td>
<td data-bind="text: v"></td>
<td><a href="#" data-bind="click: $component.delete">delete</a></td>
</tr>
</tbody>
</table>
以及ViewModel和注册码:
function KV(k, v) {
self = this;
self.k = k;
self.v = v;
}
function KVPairList(params) {
this.items = params.items;
this.keyHeading = params.keyHeading || 'Key';
this.valueHeading = params.valueHeading || 'Value';
this.k = ko.observable();
this.v = ko.observable();
}
KVPairList.prototype.add = function () {
this.items.push(new KV(this.k(), this.v()));
};
KVPairList.prototype.delete = function (item) {
this.items.remove(item);
};
function VM(params) {
this.title = params && params.heading ? params.heading : 'KO Component Example';
this.variants = ko.observableArray();
}
ko.components.register('kvlist', {
viewModel: KVPairList,
template: {
element: 'kv-list'
}
});
ko.components.register('page-main', {
viewModel: VM,
template: { element: 'wrapper' }
});
ko.applyBindings();
添加到可观察数组工作正常。但是,如果您通过错误在其中一行上单击删除:
Uncaught TypeError: Cannot read property 'remove' of undefined
看起来正在发生的事情是 $component 不是组件视图模型的上下文——它只是 foreach 绑定中的项目。我试过 $parent 也有同样的效果。
有没有办法在 foreach 循环中访问组件的视图模型?
(JS Fiddle 显示问题:http://jsfiddle.net/davetropeano/58vm9r6g/7/)
出于某种原因 'this' 在 remove 方法中没有引用 KVPairList。
这就是为什么我通常建议使用作用域变量来引用实例并防止出现此关闭问题:
试试这个:
function KVPairList(params) {
var self = this;
self.add = function(){
self.items.push(new KV(this.k(), this.v()));
};
self.delete = function(item){
self.items.remove(item);
}
self.items = params.items;
self.keyHeading = params.keyHeading || 'Key';
self.valueHeading = params.valueHeading || 'Value';
self.k = ko.observable();
self.v = ko.observable();
}
并且视图模型代码也变得更加独立。
Fiddle 这里:
JS Fiddle 显示问题:http://jsfiddle.net/davetropeano/58vm9r6g/7/
我有一个呈现可观察数组的自定义组件。列表元素是只读的,我试图支持让用户删除一个元素。
这是模板:
<template id="kv-list">
<input type="text" placeholder="key" data-bind="textInput: k">
<input type="text" placeholder="value" data-bind="textInput: v">
<button data-bind="click: add">Add</button><br>
<table>
<thead>
<tr>
<th data-bind="text: keyHeading"></th>
<th data-bind="text: valueHeading"></th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: items">
<tr>
<td data-bind="text: k"></td>
<td data-bind="text: v"></td>
<td><a href="#" data-bind="click: $component.delete">delete</a></td>
</tr>
</tbody>
</table>
以及ViewModel和注册码:
function KV(k, v) { self = this; self.k = k; self.v = v; } function KVPairList(params) { this.items = params.items; this.keyHeading = params.keyHeading || 'Key'; this.valueHeading = params.valueHeading || 'Value'; this.k = ko.observable(); this.v = ko.observable(); } KVPairList.prototype.add = function () { this.items.push(new KV(this.k(), this.v())); }; KVPairList.prototype.delete = function (item) { this.items.remove(item); }; function VM(params) { this.title = params && params.heading ? params.heading : 'KO Component Example'; this.variants = ko.observableArray(); } ko.components.register('kvlist', { viewModel: KVPairList, template: { element: 'kv-list' } }); ko.components.register('page-main', { viewModel: VM, template: { element: 'wrapper' } }); ko.applyBindings();
添加到可观察数组工作正常。但是,如果您通过错误在其中一行上单击删除:
Uncaught TypeError: Cannot read property 'remove' of undefined
看起来正在发生的事情是 $component 不是组件视图模型的上下文——它只是 foreach 绑定中的项目。我试过 $parent 也有同样的效果。
有没有办法在 foreach 循环中访问组件的视图模型?
(JS Fiddle 显示问题:http://jsfiddle.net/davetropeano/58vm9r6g/7/)
出于某种原因 'this' 在 remove 方法中没有引用 KVPairList。
这就是为什么我通常建议使用作用域变量来引用实例并防止出现此关闭问题:
试试这个:
function KVPairList(params) {
var self = this;
self.add = function(){
self.items.push(new KV(this.k(), this.v()));
};
self.delete = function(item){
self.items.remove(item);
}
self.items = params.items;
self.keyHeading = params.keyHeading || 'Key';
self.valueHeading = params.valueHeading || 'Value';
self.k = ko.observable();
self.v = ko.observable();
}
并且视图模型代码也变得更加独立。
Fiddle 这里: