Reputation: 2769
I'm making a simple to do list app to learn KnockoutJS. Right now I can add a task, and when I click the 'Remove' link, the task is removed from the view. I have a count of tasks at the bottom that uses a ko.computed function. It updates when I add a task, but when I remove a task the number stays the same. Does anyone know what's wrong with the code below?
Here's my JS:
$(function() {
var Todo = function (task, complete) {
this.task = task;
this.complete = complete;
}
var AppViewModel = function(todos) {
var self = this;
//Create an observable array of Todo objects
self.toDoItems = ko.observableArray([
{ task: "Learn KnockoutJS", complete: false}
]);
//Add a new todo
self.add = function() {
self.toDoItems.push(new Todo($('.txt').val()));
$('.txt').val('');
};
//Remove a todo
self.remove = function(item) {
self.toDoItems.destroy(item);
}
//Mark a todo complete
self.complete = function (item) {
item.complete = true;
}
//Count active tasks
self.remainingTasks = ko.computed(function() {
return self.toDoItems().length;
})
}
ko.applyBindings(new AppViewModel());
});
And here's my view:
<h3>Tasks</h3>
<table>
<tbody data-bind="foreach: toDoItems">
<tr>
<td><input type="checkbox" data-bind="click: $root.complete"></td>
<td class="todo-item"><label data-bind="text: task"></label></td>
<td class="remove"><a href="#" data-bind="click: $root.remove">Remove</a></td>
</tr>
</tbody>
</table>
<br>
<input class="txt" />
<button data-bind="click: add">Add</button><br><br>
There are <strong data-bind="text: remainingTasks"></strong> tasks here.<br>
Upvotes: 0
Views: 230
Reputation: 26730
knockout observable arrays implement two ways to delete items: remove()
, which actually removes the item from the array, and destroy()
, which just marks the items as "destroyed" but keeps it in the list. So probably remove()
is what you want, not destroy()
:
self.remove = function(item) {
self.toDoItems.remove(item);
};
Upvotes: 2
Reputation: 25551
You are calling .destroy
which doesn't actually remove the item from the array; it only adds a property to the object. This is intended to be a convenience for Rails developers as noted in the documentation.
If you change your code to call .remove
then the item will be removed from the array.
Here is a jsFiddle as an example.
Upvotes: 1