UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

244 lines (168 loc) 7.87 kB
@page can.List.prototype.attr attr @parent can.List.prototype @description Get or set elements in a List. @function can.List.prototype.attr attr @signature `list.attr()` Gets an array of all the elements in this `can.List`. @return {Array} An array with all the elements in this List. @signature `list.attr(index)` Reads an element from this `can.List`. @param {Number} index The element to read. @return {*} The value at _index_. @signature `list.attr(index, value)` Assigns _value_ to the index _index_ on this `can.List`, expanding the list if necessary. @param {Number} index The element to set. @param {*} value The value to assign at _index_. @return {can.List} This list, for chaining. @signature `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 `[can.Map::removeAttr removeAttr]`. @param {Array} elements An array of elements to merge in. @param {bool} [replaceCompletely=false] 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. @return {can.List} This list, for chaining. @body ## 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 `[can.Map.prototype.attr]` may also be enlightening. ## Events `can.List`s 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 `[can.List.prototype.splice 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 ```