can.Model.List

  • constructor
inherits: can.Observe.List

Works exactly like can.Observe.List and has all of the same properties, events, and functions as an observable list. The only difference is that when an item from the list is destroyed, it will automatically get removed from the list.

Creating a new Model List

To create a new model list, just use new {model_name}.List(ARRAY) like:

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

Model Lists in can.Model

can.Model.findAll or models will almost always be used to return a can.Model.List object, even though it is possible to create new lists like below:

var todos = Todo.models([
    new Todo( { name: "Do the dishes" } ),
    new Todo( { name: "Wash floors" } )
])

todos.constructor // -> can.Model.List

// the most correct way to get a can.Model.List
Todo.findAll({}, function(todos) {
    todos.constructor // -> can.Model.List
})

Extending can.Model.List

Creating custom can.Model.Lists allows you to extend lists with helper functions for a list of a specific type. So, if you wanted to be able to see how many todos were completed and remaining something could be written like:

Todo.List = can.Model.List({
    completed: function() {
        var completed = 0;
        this.each(function(i, todo) {
            completed += todo.attr('complete') ? 1 : 0
        })
        return completed;
    },
    remaining: function() {
        return this.attr('length') - this.completed();
    }
})

Todo.findAll({}, function(todos) {
    todos.completed() // -> 0
    todos.remaining() // -> 2
});

Removing models from model list

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

// Listen for when something is removed from the todos list.
todos.bind("remove", function( ev, oldVals, indx ) {
    console.log(oldVals[indx].attr("name") + " removed")
})

todo1.destroy(); // console shows "Do the dishes removed"