diff options
| author | Xavier Morel <xmo@openerp.com> | 2011-08-17 10:55:32 +0200 |
|---|---|---|
| committer | Xavier Morel <xmo@openerp.com> | 2011-08-17 10:55:32 +0200 |
| commit | 4ce473b8dc0dc53467fcd0520bc593866018f34e (patch) | |
| tree | 6805f3cbfd9200d7140d13e87a8827c7095d6cba /addons/base/static/src | |
| parent | ed9db7c2c74b18037dc71fbf97cf263feda77e6d (diff) | |
[ADD] basics for smarter collections to back the listview and its components
bzr revid: xmo@openerp.com-20110817085532-4chvix1odshuebvc
Diffstat (limited to 'addons/base/static/src')
| -rw-r--r-- | addons/base/static/src/js/core.js | 3 | ||||
| -rw-r--r-- | addons/base/static/src/js/list.js | 159 |
2 files changed, 161 insertions, 1 deletions
diff --git a/addons/base/static/src/js/core.js b/addons/base/static/src/js/core.js index 96c6cb1372a..5c2e6554785 100644 --- a/addons/base/static/src/js/core.js +++ b/addons/base/static/src/js/core.js @@ -10,6 +10,9 @@ openerp.base.core = function(openerp) { var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; // The base Class implementation (does nothing) + /** + * @class + */ openerp.base.Class = function(){}; // Create a new Class that inherits from this class diff --git a/addons/base/static/src/js/list.js b/addons/base/static/src/js/list.js index a0440221520..7fe995f533f 100644 --- a/addons/base/static/src/js/list.js +++ b/addons/base/static/src/js/list.js @@ -1179,7 +1179,164 @@ openerp.base.ListView.Groups = openerp.base.Class.extend( /** @lends openerp.bas }); } }); + +/** + * @class + * @extends openerp.base.Class + */ +var Events = { + /** + * @param {String} event event to listen to on the current object, null for all events + * @param {Function} handler event handler to bind to the relevant event + * @returns this + */ + bind: function (event, handler) { + var calls = this['_callbacks'] || (this._callbacks = {}); + + if (event in calls) { + calls[event].push(handler); + } else { + calls[event] = [handler]; + } + return this; + }, + /** + * @param {String} event + * @returns this + */ + trigger: function (event) { + var calls; + if (!(calls = this._callbacks)) { return this; } + var callbacks = (calls[event] || []).concat(calls[null] || []); + for(var i=0, length=callbacks.length; i<length; ++i) { + callbacks[i].apply(this, arguments); + } + return this; + } }; +var Record = openerp.base.Class.extend(/** @lends Record# */{ + /** + * @constructs + * @extends openerp.base.Class + * @borrows Events#bind as this.bind + * @borrows Events#trigger as this.trigger + * @param {Object} [data] + */ + init: function (data) { + this.data = data || {}; + }, + /** + * @param {String} key + * @returns {Object} + */ + get: function (key) { + return this.data[key]; + }, + /** + * @param key + * @param value + * @returns {Record} + */ + set: function (key, value) { + this.data[key] = value; + this.trigger('change:' + key, this, value); + this.trigger('change', this); + return this; + } +}); +Record.include(Events); +var Collection = openerp.base.Class.extend(/** @lends Collection# */{ + /** + * @constructs + * @extends openerp.base.Class + * @borrows Events#bind as this.bind + * @borrows Events#trigger as this.trigger + * @param {Array} [records] records to initialize the collection with + * @param {Object} [options] + */ + init: function (records, options) { + options = options || {}; + _.bindAll(this, '_onRecordEvent'); + this.records = []; + this._byId = {}; + this._proxies = {}; + this._key = options.key; + this._parent = options.parent; -// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: + if (records) { + this.add(records); + } + }, + /** + * @param {Object|Array} record + * @returns this + */ + add: function (record) { + var records = record instanceof Array ? record : [record]; + + for(var i=0, length=records.length; i<length; ++i) { + var instance = (records[i] instanceof Record) ? records[i] : new Record(records[i]); + instance.bind(null, this._onRecordEvent); + this._byId[instance.get('id')] = instance; + this.records.push(instance); + } + return this; + }, + + /** + * Get a record by its index in the collection, can also take a group if + * the collection is not degenerate + * + * @param {Number} index + * @param {String} [group] + * @returns {Record|undefined} + */ + at: function (index, group) { + if (group) { + var groups = group.split('.'); + return this._proxies[groups[0]].at(index, groups.join('.')); + } + return this.records[index]; + }, + /** + * Get a record by its database id + * + * @param {Number} id + * @returns {Record|undefined} + */ + get: function (id) { + if (!_(this._proxies).isEmpty()) { + var record = null; + _(this._proxies).detect(function (proxy) { + return record = proxy.get(id); + }); + return record; + } + return this._byId[id]; + }, + /** + * Builds a proxy (insert/retrieve) to a subtree of the collection, by + * the subtree's group + * + * @param {String} section group path section + * @returns {Collection} + */ + proxy: function (section) { + return this._proxies[section] = new Collection(null, { + parent: this, + key: section + }).bind(null, this._onRecordEvent); + }, + _onRecordEvent: function (event, record, options) { + this.trigger.apply(this, arguments); + } +}); +Collection.include(Events); +openerp.base.list = { + Events: Events, + Record: Record, + Collection: Collection +} +}; +// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax: |
