0

I'm struggling to understand how calling destroy on a model instance is supposed to affect the Model.List it's attached to.

The documentation states that:

One advantage that can.Model.List has over a traditional can.List is that when you destroy a model, if it is in that list, it will automatically be removed from the list.

However when I run this code:

var Todo = can.Model.extend({
  destroy: function() {
    console.log("Calling destroy function");                                            
    return can.Deferred();
  }       
},{})   

Todo.bind("destroyed", function(ev, todo) {                                             
   console.log("Todo \"" + toto.name + "has been destroyed");                           
}); 


var todo1 = new Todo({ name: "Do the dishes", id: 1 });                                 
var todo2 =   new Todo({ name: "Wash floors", id: 2 });                                 
var todos = new can.Model.List([todo1, todo2]);                                         

todos.bind("remove", function( ev, oldVals, indx ) {                                    
  console.log("todo"+indx+" removed")
})         

console.log("Before destroy I have " + todos.length + " elements");                     
console.log("First element is \"" + todos[0].name + "\"");                              
var destroyed = todos[0].destroy()
console.log("After destroy I have " + todos.length + " elements");                      
console.log("First element is \"" + todos[0].name + "\"");

Here is what I see in the console:

Before destroy I have 2 elements
First element is "Do the dishes"
Calling destroy function
After destroy I have 2 elements
First element is "Do the dishes"

Why is the element still in the Model.List after calling destroyed? Why aren't the destroyed and remove events triggered?

Note that in the real-world code I'm trying to debug, calling destroy does trigger a DELETE request and the object gets deleted on the server as expected. However it doesn't get removed from the Model.List and therefore neither from the associated view.

ramblinjan
  • 6,578
  • 3
  • 30
  • 38
Alex Marandon
  • 4,034
  • 2
  • 17
  • 21
  • It might not happen in your real-life code, but in your example above, the Deferred returned from `destroy` never seems to get resolved (and therefore the Todo will never be removed). – Daff Feb 24 '14 at 15:06

1 Answers1

2

By declaring the destroy method in you model definition you are overriding the default destroy method that takes care of removing the element from the list. So you need to remove that method from there, or call super.

Here is a fiddle that shows this working http://jsbin.com/zunox/1/edit

Sebastian
  • 2,249
  • 17
  • 20
  • I see, my code example introduced a different issue because I wanted it to be self-contained and didn't know about can.fixture. The code I'm trying to debug doesn't actually override the destroy method, it uses a string just like in you fiddle. Actually if I add a fixture to the problematic code, the model instance does get removed from the list. The code I'm trying to debug is from the book Seven Web Frameworks in Seven Weeks: http://forums.pragprog.com/forums/250/topics/12549 So now I don't know how to reproduce it without the server running. +1 for you anyway since I learnt from you answer. – Alex Marandon Feb 24 '14 at 20:25