2016-05-25 2 views
2

Почему я не могу удалить элементы из массива?Undefined не является объектом при оценке 'this.list.remove'

Вид 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); 
}); 

ответ

-1

Вы можете поставить как следующий

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

I думаю, что вы не положили себя

+0

Это будет ошибка синтаксиса. 'self.list' не будет работать как ключ объекта. – DonovanM

+0

на самом деле он не поставил свой массив в наблюдаемом и пытался удалить что-то, чтобы он не работал, я думаю –

1

Вы должны прочитать на the this keyword.

Первая проблема связана с объектом внутри объекта буквально.

Внутри объекта буквально, this будет не обратитесь к этому объекту. В вашем коде он будет ссылаться на document, так как ближайший объем - это установка $(function() { ... });, что эквивалентно (см. docs) $(document).ready(...), где this (несколько более очевидно) привязано к document.

Вот пример, чтобы показать это, A, B и C все входа то же самое (что неviewModel):

console.log(this.document); // A 
 

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

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

Заметим также, что this внутри ваша функция removeItem будет ссылаться на ее ближайшей области действия по умолчанию, которая является самой функцией removeItem (а не window, document, или viewModel).

Решение 1: если вы действительно хотите использовать литералы объектов, вы можете сначала объявить объект и добавить его свойство позже, например:

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

Решения 2: если вы хотите использовать the self = this idiom Я рекомендую использовать функцию конструктора вместо:

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

Для о.е. т, что последнее предложение в полностью работоспособный пример:

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);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script> 
 

 
<table> 
 
    <tbody data-bind="foreach: list"> 
 
    <tr> 
 
     <td data-bind="text: name"></td> 
 
     <td><a href="#">Edit</a></td> 
 
     <td><a href="#" data-bind="click: $root.removeItem">Delete</a></td> 
 
    </tr> 
 
    </tbody> 
 
</table>

Смежные вопросы