3.0 beta 2

Collections

Collections in ActiveWidgets combine the features of a hash table and an array. It is possible to assign and retrieve elements using an index (number) or a key (string).

Collection can be generic, which make no assumptions regarding the type of its elements, or associated with a particular type. The 'typed' collection may create elements automatically using a shared prototype, for example, when bound to a data source or assigned an array of config objects.

Generic collections

The generic collections are represented by AX.Collection class. It should be used when the collection elements are primitive value types (number, string). Collections containing objects should be of AX.Object.Collection type or other typed collection.

Initialization

Collection can be initialized with either an array or a hash table.

var items = new AX.Collection(['abc', 'def', 'xyz']);

When using an array, the collection automatically generates the keys for each element. With a hash table, you provide the keys, and the collection adds the elements in the same order as they are stored in a hash table.

var items = new AX.Collection({
    a: 123,
    b: 456,
    c: 789
});

Accessing elements

To retrieve an element from the collection use get() method. The argument can be a number (index) or a string (key).

var item = items.get(i);

The set() method adds an element either at specified position (the argument is number/index, the key is generated automatically) or at the end of the collection (when the argument is string/key).

items.set(i, element);

When the collection is a property of a another object, the element accessor method is automatically added to the parent object. The name of the accessor method is the name of collection property but in a singular form. One argument (index/key) invokes collection get() method, while two arguments (index/key, value) invoke collection set().

var obj = new AX.Object({
    items: new AX.Collection(['x', 'y', 'z'])
});

// item method is added automatically
var x = obj.item(0);

// assign an element to the items collection
obj.item(1, 'yy');

There are also add(), remove() methods to add/remove elements, and count() method to get the current number of elements.

Calculated elements

The collections can contain functions as its elements (i.e. calculated elements).

var obj = new AX.HTML({
    width: '100px'
});

// assign calculated element to the styles collection
obj.style('width', function(){
    return this.width();
});

obj.width('200px');

The calculated elements (functions) get executed in the context of the parent object.

Iterations

The each() method allows simple iterations.

items.each(function(value, index, key){
    // do something
});

If the function returns something other than undefined, the iteration stops and the result is returned.

Object collections (typed)

The typed collections are associated with a particular type and are defined automatically when creating a new type.

// defining a new type
var MyType = AX.Object.extend({
    text: '',
    value: 0
});

// object instance of the new type
var obj = new MyType();

// the collection of MyType objects
var items = new MyType.Collection();

In the above example the MyType.Collection constructor is created simultaneously with MyType constructor by AX.Object.extend() call.

Auto elements

The typed collection assumes that each of its elements is an object and can create it automatically on access or on the assignment.

// new collection of 5 html elements
var items = new AX.HTML.Collection(5);

// new html element created on access
var html = items.get(0);

// assigning config to automatically created element
items.add({
    tag: 'div',
    innerHTML: 'hello'
});

The same principle applies when the typed collection is initialized with an array of config objects. The collection automatically creates and then configures each element.

grid.columns([
    {header: 'Col 1', width: 100},
    {header: 'Col 2', width: 120},
    {header: 'Col 3', width: 150},
]);

It is still possible to assign existing ActiveWidgets objects as elements of the typed collection.

var items = new AX.HTML.Collection();

var obj = new AX.Component();

items.add(obj);

The collection elements are not children of the collection object. Its parent property refers to the collection parent, not the collection itself.

References

In many cases it is better to insert a reference to the existing object rather than an object itself into the collection. This can be done with a special config string (property name with '@' prefix) -

var obj = new AX.Object({

    child1: new AX.Object(),
    child2: new AX.Object(),

    items: new AX.Object.Collection()
});

// add reference to the child1 object
obj.items().add('@child1');

Internally, the reference is implemented as calculated element (function, which finds and returns a property with a given name).