Knockout.js $component在KO组件内的foreach绑定中不正确

Knockout.js $component在KO组件内的foreach绑定中不正确,knockout.js,knockout-components,Knockout.js,Knockout Components,JS小提琴显示问题: 我有一个自定义组件,它呈现一个可观察的数组。列表元素是只读的,我试图支持让用户删除元素 以下是模板: <template id="kv-list"> <input type="text" placeholder="key" data-bind="textInput: k"> <input type="text" placeholder="value" data-bind="textInput: v"> <button data-bi

JS小提琴显示问题:

我有一个自定义组件,它呈现一个可观察的数组。列表元素是只读的,我试图支持让用户删除元素

以下是模板:

<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>
看起来,$component不是组件的viewmodel的上下文,它只是foreach绑定中的项。我试过$parent,效果也一样

有没有办法在foreach循环中访问组件的viewmodel


JS Fiddle显示问题:

由于某种原因,remove方法中的“this”未重新传递到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();   
}
视图模型代码也变得更加独立

在这里拉小提琴:


谢谢我总是用self=这个形式,不管出于什么原因,这次没有用。我发现如果不想使用自变量,也可以在原型上使用.bindthis。this.delete=函数{…}.bindthis;检查我对这个问题的评论。“this”不是KVPairList的原因很简单。data bind=click:$component.delete.bind$component应该可以工作。现在您只是将一个函数传递给click绑定。它不知道这个函数来自哪里,这意味着它不能用正确的上下文调用它。data bind=click:function{$component.delete$data}也可以工作,因为这样您就可以在视图模型上调用delete函数,从而为其提供正确的上下文。使用self完全避免需要处理调用上下文也是Luis回答的一个选项。
Uncaught TypeError: Cannot read property 'remove' of undefined
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();   
}