attr

  • function
can.List.prototype.attr  

Get or set elements in a List.

list.attr()

Gets an array of all the elements in this can.List.

Returns

{Array}

An array with all the elements in this List.

list.attr(index)

Reads an element from this can.List.

Parameters

  1. index {Number}

    The element to read.

Returns

{*}

The value at index.

list.attr(index, value)

Assigns value to the index index on this can.List, expanding the list if necessary.

Parameters

  1. index {Number}

    The element to set.

  2. value {*}

    The value to assign at index.

Returns

{can.List}

This list, for chaining.

list.attr(elements[, replaceCompletely])

Merges the members of elements into this List, replacing each from the beginning in order. If elements is longer than the current List, the current List will be expanded. If elements is shorter than the current List, the extra existing members are not affected (unless replaceCompletely is true). To remove elements without replacing them, use removeAttr.

Parameters

  1. elements {Array}

    An array of elements to merge in.

  2. replaceCompletely=false {bool}Optional

    whether to completely replace the elements of List

    If replaceCompletely is true and elements is shorter than the List, the existing extra members of the List will be removed.

Returns

{can.List}

This list, for chaining.

Use

attr gets or sets elements on the can.List it's called on. Here's a tour through how all of its forms work:

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

 // set an element:
 people.attr(0, 'Adam');

 // 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']

Deep properties

attr can also set and read deep properties. All you have to do is specify the property name as you normally would if you weren't using attr.

var people = new can.List([{name: 'Alex'}, {name: 'Bob'}]);

// set a property:
people.attr('0.name', 'Alice');

// get a property:
people.attr('0.name');  // 'Alice'
people[0].attr('name'); // 'Alice'

// get all properties:
people.attr(); // [{name: 'Alice'}, {name: 'Bob'}]

The discussion of deep properties under attr may also be enlightening.

Events

can.Lists emit five types of events in response to changes. They are:

  • 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.

The change event

The first event that is fired is the change event. The change event is useful if you want to react to all changes on an List.

var list = new can.List([]);
list.bind('change', function(ev, index, how, newVal, oldVal) {
    console.log('Something changed.');
});

The parameters of the event handler for the change event are:

  • ev The event object.
  • index Where the change took place.
  • how Whether elements were added, removed, or set. Possible values are 'add', 'remove', or 'set'.
  • newVal The elements affected after the change newVal will be a single value when an index is set, an Array when elements were added, and undefined if elements were removed.
  • oldVal The elements affected before the change. newVal will be a single value when an index is set, an Array when elements were removed, and undefined if elements were added.

Here is a concrete tour through the change event handler's arguments:

var list = new can.List();
list.bind('change', function(ev, index, how, newVal, oldVal) {
    console.log(ev + ', ' + index + ', ' + how + ', ' + newVal + ', ' + oldVal);
});

list.attr(['Alexis', 'Bill']); // [object Object], 0, add, ['Alexis', 'Bill'], undefined
list.attr(2, 'Eve');           // [object Object], 2, add, Eve, undefined
list.attr(0, 'Adam');          // [object Object], 0, set, Adam, Alexis
list.attr(['Alice', 'Bob']);   // [object Object], 0, set, Alice, Adam
                               // [object Object], 1, set, Bob, Bill
list.removeAttr(1);            // [object Object], 1, remove, undefined, Bob

The set event

set events are fired when an element at an index that already exists in the List is modified. Actions can cause set events to fire never also cause length events to fire (although some functions, such as splice may cause unrelated sets of events to fire after being batched).

The parameters of the event handler for the set event are:

  • ev The event object.
  • newVal The new value of the element.
  • index where the set took place.

Here is a concrete tour through the set event handler's arguments:

var list = new can.List();
list.bind('set', function(ev, newVal, index) {
    console.log(newVal + ', ' + index);
});

list.attr(['Alexis', 'Bill']);
list.attr(2, 'Eve');
list.attr(0, 'Adam');          // Adam, 0
list.attr(['Alice', 'Bob']);   // Alice, 0
                               // Bob, 1
list.removeAttr(1);

The add event

add events are fired when elements are added or inserted into the List.

The parameters of the event handler for the add event are:

  • ev The event object.
  • newElements The new elements. If more than one element is added, newElements will be an array. Otherwise, it is simply the new element itself.
  • index Where the add or insert took place.

Here is a concrete tour through the add event handler's arguments:

var list = new can.List();
list.bind('add', function(ev, newElements, index) {
    console.log(newElements + ', ' + index);
});

list.attr(['Alexis', 'Bill']); // ['Alexis', 'Bill'], 0
list.attr(2, 'Eve');           // Eve, 2
list.attr(0, 'Adam');
list.attr(['Alice', 'Bob']);

list.removeAttr(1);

The remove event

remove events are fired when elements are removed from the list.

The parameters of the event handler for the remove event are:

  • ev The event object.
  • removedElements The removed elements. If more than one element was removed, removedElements will be an array. Otherwise, it is simply the element itself.
  • index Where the removal took place.

Here is a concrete tour through the remove event handler's arguments:

var list = new can.List();
list.bind('remove', function(ev, removedElements, index) {
    console.log(removedElements + ', ' + index);
});

list.attr(['Alexis', 'Bill']);
list.attr(2, 'Eve');
list.attr(0, 'Adam');
list.attr(['Alice', 'Bob']);

list.removeAttr(1);            // Bob, 1

The length event

length events are fired whenever the list changes.

The parameters of the event handler for the length event are:

  • ev The event object.
  • length The current length of the list. If events were batched when the length event was triggered, length will have the length of the list when stopBatch was called. Because of this, you may receive multiple length events with the same length parameter.

Here is a concrete tour through the length event handler's arguments:

var list = new can.List();
list.bind('length', function(ev, length) {
    console.log(length);
});

list.attr(['Alexis', 'Bill']); // 2
list.attr(2, 'Eve');           // 3
list.attr(0, 'Adam');
list.attr(['Alice', 'Bob']);

list.removeAttr(1);            // 2