From 9022aae8cb1122df0c9a108b2905e37949bd73b1 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 1 Mar 2012 11:21:17 +0100 Subject: [PATCH] [ADD] core Traverser API There are still questions over how it'll work, and if it can work at all bzr revid: xmo@openerp.com-20120301102117-zxd89ffcvo2n32nw --- addons/web/static/src/js/data.js | 79 ++++++++++++++++++++++++++++++++ doc/source/rpc.rst | 69 ++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) diff --git a/addons/web/static/src/js/data.js b/addons/web/static/src/js/data.js index 969f3542908..27d4562aafb 100644 --- a/addons/web/static/src/js/data.js +++ b/addons/web/static/src/js/data.js @@ -261,6 +261,85 @@ openerp.web.Model = openerp.web.Class.extend(/** @lends openerp.web.Model# */{ }, }); +openerp.web.Traverser = openerp.web.Class.extend(/** @lends openerp.web.Traverser# */{ + /** + * @constructs openerp.web.Traverser + * @extends openerp.web.Class + * + * @param {openerp.web.Model} model instance this traverser is bound to + */ + init: function (model) { + this._model = model; + this._index = 0; + }, + + /** + * Gets and sets the current index + * + * @param {Number} [idx] + * @returns {Number} current index + */ + index: function (idx) { + if (idx) { this._index = idx; } + return this._index; + }, + /** + * Returns the model this traverser is currently bound to + * + * @returns {openerp.web.Model} + */ + model: function () { + return this._model; + }, + /** + * Fetches the size of the backing model's match + * + * @returns {Deferred} deferred count + */ + size: function () { + return this._model.query().count(); + }, + + /** + * Record at the current index for the collection, fails if there is no + * record at the current index. + * + * @returns {Deferred<>} + */ + current: function (fields) { + return this._model.query(fields).first().pipe(function (record) { + if (record == null) { + return $.Deferred() + .reject('No record at index' + this._index) + .promise(); + } + return record; + }); + }, + next: function (fields) { + var self = this; + this._index++; + return this.size().pipe(function (s) { + if (self._index >= s) { + self._index = 0; + } + return self.current(fields); + }); + }, + previous: function (fields) { + var self = this; + this._index--; + if (this._index < 0) { + return this.size().pipe(function (s) { + self._index = s-1; + return self.current(fields); + }); + } + return this.current(fields); + } + +}); + openerp.web.DataGroup = openerp.web.OldWidget.extend( /** @lends openerp.web.DataGroup# */{ /** * Management interface between views and grouped collections of OpenERP diff --git a/doc/source/rpc.rst b/doc/source/rpc.rst index ea426916932..1192b28971f 100644 --- a/doc/source/rpc.rst +++ b/doc/source/rpc.rst @@ -170,6 +170,75 @@ around and use them differently/add new specifications on them. (``?`` field) and the inability to "drill down" into relations for sorting. +Synchronizing views (provisional) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. note:: this API may not be final, and may not even remain + +While the high-level RPC API is mostly stateless, some objects in +OpenERP Web need to share state information. One of those is OpenERP +views, especially between "collection-based" views (lists, graphs) and +"record-based" views (forms, diagrams), which gets its very own API +for traversing collections of records, the aptly-named +:js:class:`~openerp.web.Traverser`. + +A :js:class:`~openerp.web.Traverser` is linked to a +:js:class:`~openerp.web.Model` and is used to iterate over it +asynchronously (and using indexes). + +.. js:class:: openerp.web.Traverser(model) + + .. js:function:: openerp.web.Traverser.model() + + :returns: the :js:class:`~openerp.web.Model` this traverser + instance is bound to + + .. js:function:: openerp.web.Traverser.index([idx]) + + If provided with an index parameter, sets that as the new + index for the traverser. + + :param Number idx: the new index for the traverser + :returns: the current index for the traverser + + .. js:function:: openerp.web.Traverser.current([fields]) + + Fetches the traverser's "current" record (that is, the record + at the current index of the traverser) + + :param Array fields: fields to return in the record + :rtype: Deferred<> + + .. js:function:: openerp.web.Traverser.next([fields]) + + Increases the traverser's internal index by one, the fetches + the corresponding record. Roughly equivalent to: + + .. code-block:: javascript + + var idx = traverser.index(); + traverser.index(idx+1); + traverser.current(); + + :param Array fields: fields to return in the record + :rtype: Deferred<> + + .. js:function:: openerp.web.Traverser.previous([fields]) + + Similar to :js:func:`~openerp.web.Traverser.next` but iterates + the traverser backwards rather than forward. + + :param Array fields: fields to return in the record + :rtype: Deferred<> + + .. js:function:: openerp.web.Traverser.size() + + Shortcut to checking the size of the backing model, calling + ``traverser.size()`` is equivalent to calling + ``traverser.model().query([]).count()`` + + :rtype: Deferred + Low-level API: RPC calls to Python side ---------------------------------------