评估'this.list.remove'时,未定义不是对象

时间:2016-05-25 17:12:20

标签: javascript web knockout.js knockout-3.0

为什么我无法从数组中删除项目?

html视图,我试图显示数组的所有对象:

<tbody data-bind="foreach:list" >
<tr> 
  <td data-bind="text:name" class="span10"></td> 
  <td><a class="icon-pencil" href="#"></a>Edit</td>
   here every time you click at the <a> tag i want to remove an element of the array. but it is not working
  <td><a class="icon-trash" href="#" data-bind="click:$root.removeItem " >
  </a>Delete</td>
</tr>
</tbody>

剧本:

$(function () {
   var customers=[
      {name:'robert'},
      {name:'miguel'},
      {name:'felipe'},
      {name:'juan'},
      {name:'danilo'},
      {name:'federico'}
     ];

     var viewModel = {

        self:this,

        list: ko.observableArray(customers),

        // it's not removing the item of the array.
        removeItem: function(place) {
            this.list.remove(place);
        }
    };
    ko.applyBindings(viewModel);
});

2 个答案:

答案 0 :(得分:1)

您应该阅读the this keyword

第一个问题是对象文字中的self:this事物。

在对象文字中,this引用该对象。在您的代码中,它将引用document,因为最近的范围是$(function() { ... });设置,相当于(请参阅docs$(document).ready(...)其中this (更明显地)与document绑定。

以下是一个示例,A,B和C都记录了相同的内容( viewModel):

&#13;
&#13;
console.log(this.document); // A

$(function() {
  var customers = [{
    name: 'robert'
  }];
  
  console.log(this); // B

  var viewModel = {
    self: this
  };
  
  console.log(viewModel.self); // C
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

另请注意,this函数中的removeItem默认情况下会引用最近的函数作用域,这是removeItem函数本身(而不是{ {1}},windowdocument)。

解决方案1 ​​:如果您真的想使用对象文字,可以先声明对象并稍后添加其属性,例如:

viewModel

解决方案2 :如果您想使用the self = this idiom,我建议使用构造函数:

var viewModel = {};
viewModel.list = ko.observableArray(customers);
viewModel.removeItem = function(place) {
  viewModel.list.remove(place);
};

将最后一个建议放入一个完全可运行的例子中:

&#13;
&#13;
function ViewModelConstructor(myCustomers) {
  var self = this;
  self.list = ko.observableArray(myCustomers);
  self.removeItem = function(place) {
      self.list.remove(place);
  };
}

// Get an instance:
var viewModel = new ViewModelConstructor(customers);
&#13;
var customers=[
  {name:'robert'},
  {name:'miguel'},
  {name:'felipe'},
  {name:'juan'}
];

function ViewModelConstructor(myCustomers) {
  var self = this;
  self.list = ko.observableArray(myCustomers);
  self.removeItem = function(place) {
      self.list.remove(place);
  };
}

// Get an instance:
var viewModel = new ViewModelConstructor(customers);

ko.applyBindings(viewModel);
&#13;
&#13;
&#13;

答案 1 :(得分:-1)

你可以像下面这样说吗

self:this,
self.list :  ko.observableArray(customers),

我认为你没有把自己