/// <reference path="../util/ArrayUtils.ts" /> /// <reference path="./IListFilter.ts" /> var econda; (function (econda) { var collection; (function (collection) { var ArrayUtils = econda.util.ArrayUtils; /** * Generic class for lists. * @class econda.collection.List */ var List = (function () { function List(cfg) { // should be protected, but this is not possible in current typescript version. Fix as soon as available. this._items = []; this._itemsById = {}; this._idProperty = null; /** * Callbacks on all list changes (add, remove, clear) */ this.onChange = []; if (cfg instanceof List) { return cfg; } if (typeof cfg === 'object') { this._idProperty = cfg.idProperty || null; this._items = []; if (typeof cfg.items !== 'undefined') { this._setItems(cfg.items); } if (typeof cfg.onChange !== 'undefined') { this.setOnChange(cfg.onChange); } } } List.prototype.setOnChange = function (callback) { ArrayUtils.isArray(callback) ? this.onChange = callback : this.onChange = [callback]; }; /** * Run callbacks registered for onChange event. * @private */ List.prototype._fireOnChangeEvent = function (item) { for (var i = 0; i < this.onChange.length; i++) { this.onChange[i](item); } }; /** * Add item to list */ List.prototype.add = function (item) { this._items.push(item); if (this._idProperty !== null && typeof item[this._idProperty] != 'undefined') { this._itemsById["" + item[this._idProperty]] = item; } this._collectionChanged(); this._fireOnChangeEvent(item); return this; }; /** * True if given item exists in collection * @param {Object} needle * @returns {Boolean} */ List.prototype.contains = function (needle) { return ArrayUtils.contains(this._items, needle); }; /** * Returns number of items in collection * @returns {Number} */ List.prototype.length = function () { return this._items.length; }; List.prototype.sort = function (compareFunctionOrProperty) { var compareFunction = (typeof compareFunctionOrProperty === 'string') ? this._createCompareFunction(compareFunctionOrProperty) : compareFunctionOrProperty; return this._items.sort(compareFunction); }; List.prototype._createCompareFunction = function (propertyName) { return function (a, b) { if (a[propertyName] > b[propertyName]) return 1; if (a[propertyName] < b[propertyName]) return -1; return 0; }; }; /** * Get index of given item * @param {Object} needle * @returns {Number} */ List.prototype.indexOf = function (needle) { return ArrayUtils.indexOf(this._items, needle); }; /** * Get item by id. idProperty must have been configured in constructor * @param {String} id * @returns {Object} */ List.prototype.getItemById = function (id) { if (typeof this._itemsById["" + id] === 'undefined') { return null; } return this._itemsById["" + id]; }; /** * Get item at index. Returns null if no item exists at given index. * @param {Number} index */ List.prototype.get = function (index) { return (typeof this._items[index] !== 'undefined') ? this._items[index] : null; }; /** * Get all items * @returns {ItemType[]} */ List.prototype.getAll = function () { return this._items; }; List.prototype.getFilteredItems = function (filter) { var matches = []; if (typeof filter.match === 'function') { // object that implements IListFilter for (var n = 0; n < this._items.length; n++) { if (filter.match(this._items[n]) === true) { matches.push(this._items[n]); } } } else { // filter function for (var n = 0; n < this._items.length; n++) { if (filter(this._items[n]) === true) { matches.push(this._items[n]); } } } return matches; }; /** * Executes callback function with each item in collection */ List.prototype.forEach = function (callback, scope) { for (var n = 0; n < this._items.length; n++) { callback.call(scope, this._items[n]); } }; /** * Remove all items from collection */ List.prototype.clear = function () { this._setItems(null); return this; }; List.prototype._setItems = function (items) { this._items = []; this._itemsById = {}; if (items === null) { return; } // array as parameter if (typeof items.length !== 'undefined') { this._items = items; } else if (typeof items === 'object') { // object as parameter for (var propertyName in items) { if (items.hasOwnProperty(propertyName)) { this._items.push(items[propertyName]); } } } if (this._idProperty !== null) { for (var n = 0; n < this._items.length; n++) { this._itemsById["" + this._items[n][this._idProperty]] = this._items[n]; } } this._collectionChanged(); this.forEach(this._fireOnChangeEvent, this); }; /** * Callback for extending classes. Called one time if items in collection were added or removed. * Must be called before any events are fired. */ List.prototype._collectionChanged = function () { }; return List; }()); collection.List = List; })(collection = econda.collection || (econda.collection = {})); })(econda || (econda = {}));