can.Observe.List

  • constructor
inherits: can.Observe

Use for observable array-like objects.

new can.Observe.List([array])

Create an observable array-like object.

Parameters

  1. array {Array}Optional

    items to seed the List with

Returns

{can.Observe.List}

an instance of can.Observe.List with the elements from array

can.Observe.List([name,] [staticProperties,] instanceProperties)

Creates a new extended constructor function.

This is deprecated. In CanJS 1.2, by default, calling the constructor function without new will create a new instance. Use can.Observe.extend instead of calling the constructor to extend.

Working with Lists

can.Observe.List extends can.Observe, so all the ways that you're used to working with Observes also work here, including bind, unbind, and each. And just as you can directly read properties normally off of an Observe, you can use array accessors ([]) to read elements directly off of a List.

The one function of can.Observe that works slightly differently is attr. As expected when working with arrays, top-level keys passed into attr are required to be numeric. (Strings may still be used when getting or modifying deep properties). Any top-level keys that are non-numeric are ignored. In addition, as might be expected, a call to argument-less attr returns an array instead of an object.

Just as you shouldn't set properties of an Observe directly, you shouldn't change elements of a List directly. Always use attr to set the elements of a List, or use push, pop, shift, unshift, or splice.

Here is a tour through the forms of can.Observe.List's attr that parallels the one found under attr:

var people = new can.Observe.List(['Alex', 'Bill']);

// set an element:
people.attr(0, 'Adam');
people[0] = 'Adam'; // don't do this!

// get an element:
people.attr(0); // 'Adam'
people[0]; // 'Adam'

// get all elements:
people.attr(); // ['Adam', 'Bill']

// extend the array:
people.attr(4, 'Charlie');
people.attr(); // ['Adam', 'Bill', undefined, undefined, 'Charlie']

// merge the elements:
people.attr(['Alice', 'Bob', 'Eve']);
people.attr(); // ['Alice', 'Bob', 'Eve', undefined, 'Charlie']

Listening to changes

As with can.Observes, the real power of observable arrays comes from being able to react to changes in the member elements of the array. Lists emit five types of events:

  • the change event fires on every change to a List.
  • the set event is fired when an element is set.
  • the add event is fired when an element is added to the List.
  • the remove event is fired when an element is removed from the List.
  • the length event is fired when the length of the List changes.

This example presents a brief concrete survey of the times these events are fired:

var list = new can.Observe.List(['Alice', 'Bob', 'Eve']);

list.bind('change', function() { console.log('An element changed.'); });
list.bind('set', function() { console.log('An element was set.'); });
list.bind('add', function() { console.log('An element was added.'); });
list.bind('remove', function() { console.log('An element was removed.'); });
list.bind('length', function() { console.log('The length of the list changed.'); });

list.attr(0, 'Alexis'); // 'An element changed.'
                        // 'An element was set.'

list.attr(3, 'Xerxes'); // 'An element changed.'
                        // 'An element was added.'
                        // 'The length of the list was changed.'

list.attr(['Adam', 'Bill']); // 'An element changed.'
                             // 'An element was set.'
                             // 'An element was changed.'
                             // 'An element was set.'

list.pop(); // 'An element changed.'
            // 'An element was removed.'
            // 'The length of the list was changed.'

More information about binding to these events can be found under attr.