2015-05-12 31 views
1

JS小提琴显示问题结合中不正确: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> 

和视图模型和注册码:

 

    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(); 

添加到观察的阵列工作正常。但是,如果你点击其中一列删除KO得来的错误:

Uncaught TypeError: Cannot read property 'remove' of undefined 

它看起来像正在发生的事情是,$分量不是组件的视图模型的背景 - 它只是在foreach内的项目捆绑。我试过$父母具有相同的效果。

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

(JS小提琴显示问题:http://jsfiddle.net/davetropeano/58vm9r6g/7/

+0

'数据绑定= “点击:$ component.delete.bind($组件)”'应该工作。现在你只是将一个函数传递给点击绑定。它不知道该函数从哪里来,这意味着它不能用正确的上下文来调用它。 'data-bind =“click:function(){$ component.delete($ data)}”'也可以工作,因为这样你就可以调用delete函数__on__提供正确上下文的视图模型。 – CrimsonChris

+0

使用'self'完全避免处理调用上下文的需要也是Luis回答的一个选项。 – CrimsonChris

回答

0

出于某种原因, '这个' remove方法里面没有refferring到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(); 
} 

和视图模型代码变得更加自足以及。

小提琴这里:

http://jsfiddle.net/luisvsilva/uzs7qhbs/1/

+0

谢谢。我总是使用'''self = this'''表单,并且因为任何原因没有这次。如果你不想使用''''''''''''变量,我发现你也可以在原型上使用'''.bind(this)''。 '''this.delete = function(){...} .bind(this);''' – davetropeano

+0

检查我对这个问题的评论。 “this”不是“KVPairList”的原因非常简单。 – CrimsonChris