diff options
| author | Aaron Bohy <aab@odoo.com> | 2016-03-16 09:53:23 +0100 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2016-03-18 10:44:52 +0100 |
| commit | 002660a9b05cf8620e1c5287a8538ac5e806d59e (patch) | |
| tree | f113231aa09c7836905510d781f7f23457abfed4 /addons/web/static/src/js/framework | |
| parent | 141f4d95bd57f24fb06636a0720cc3665caac39d (diff) | |
[IMP] openerp, web(_*): batch views RPCs
Load the fields_view of all views of the action together. If a searchview is
required, also load its fields_view and its filters.
Use lazy-loading for fields as they are required for the Pivot and Graph
views only, and may be used by Filters and GroupBy menus of the Search view
if the users clicks on 'Add a custom Filter/Group'.
The fields are thus also loaded directly if the first view of the action is
Pivot or Graph, and otherwise, they are lazy-loaded when/if the user opens
a Pivot or Graph view, or if he wants to add a custom Filter/Group.
Some refactoring of views API as well:
- Views must now be instantiated with their fields_view
- Move code requiring fields_view from start() to init(), or willStart() for
heavy processing.
- Remove view_type attribute from views as it was used to call
fields_view_get.
- Remove view_id parameter to views' init as it is no longer used.
- Move duplicate code from various views' init to the View widget.
- Remove view_loading() function from views as they now follow the classical
lifecycle of widgets (init -> willStart -> start -> destroy).
- Searchview now extends View like all other views.
- Remove useless function guard_active() as it was used for the form_view's
action buttons to wrap handlers to ensure that they are executed only if
the form_view is the current active view. This is not useful anymore as
from v9, views and their control panel are appended in the DOM
simultaneously, so one can't click on a button of a view which is not the
current active view.
Diffstat (limited to 'addons/web/static/src/js/framework')
| -rw-r--r-- | addons/web/static/src/js/framework/model.js | 34 | ||||
| -rw-r--r-- | addons/web/static/src/js/framework/view.js | 103 |
2 files changed, 40 insertions, 97 deletions
diff --git a/addons/web/static/src/js/framework/model.js b/addons/web/static/src/js/framework/model.js index 2621ca490d4..8e37f14218e 100644 --- a/addons/web/static/src/js/framework/model.js +++ b/addons/web/static/src/js/framework/model.js @@ -82,29 +82,31 @@ var Model = Class.extend({ * @param {Boolean} [args.toolbar=false] get the toolbar definition */ fields_view_get: function (options) { - return this.call('fields_view_get', { view_id: options.view_id, view_type: options.view_type, context: options.context, toolbar: options.toolbar || false - }).then(function postprocess(fvg) { - var doc = $.parseXML(fvg.arch).documentElement; - fvg.arch = utils.xml_to_json(doc, (doc.nodeName.toLowerCase() !== 'kanban')); - if ('id' in fvg.fields) { - // Special case for id's - var id_field = fvg.fields.id; - id_field.original_type = id_field.type; - id_field.type = 'id'; - } - _.each(fvg.fields, function(field) { - _.each(field.views || {}, function(view) { - postprocess(view); - }); + }).then(this.postprocess_fvg.bind(this)); + }, + + postprocess_fvg: function (fvg) { + var self = this; + var doc = $.parseXML(fvg.arch).documentElement; + fvg.arch = utils.xml_to_json(doc, (doc.nodeName.toLowerCase() !== 'kanban')); + if ('id' in fvg.fields) { + // Special case for id's + var id_field = fvg.fields.id; + id_field.original_type = id_field.type; + id_field.type = 'id'; + } + _.each(fvg.fields, function(field) { + _.each(field.views || {}, function(view) { + self.postprocess_fvg(view); }); - return fvg; }); - } + return fvg; + }, }); return Model; diff --git a/addons/web/static/src/js/framework/view.js b/addons/web/static/src/js/framework/view.js index 29307b61833..b6153475b0b 100644 --- a/addons/web/static/src/js/framework/view.js +++ b/addons/web/static/src/js/framework/view.js @@ -14,10 +14,11 @@ var View = Widget.extend({ this.do_action(action_data); } }, + defaults: { + action: {}, + }, // name displayed in view switchers display_name: '', - // define a view type for each view to allow automatic call to fields_view_get. - view_type: undefined, // used by views that need a searchview. searchable: true, // used by views that need a searchview but don't want it to be displayed. @@ -27,57 +28,28 @@ var View = Widget.extend({ multi_record: true, // icon is the font-awesome icon to display in the view switcher icon: 'fa-question', - init: function(parent, dataset, view_id, options) { + // whether or not the view requires the model's fields to render itself + require_fields: false, + init: function(parent, dataset, fields_view, options) { this._super(parent); this.ViewManager = parent; this.dataset = dataset; - this.view_id = view_id; - this.set_default_options(options); - }, - start: function () { - return this.load_view(); + this.model = dataset.model; + this.fields_view = fields_view; + this.options = _.defaults({}, options, this.defaults); }, - load_view: function() { - var self = this; - var view_loaded_def; - if (this.embedded_view) { - view_loaded_def = $.Deferred(); - $.async_when().done(function() { - view_loaded_def.resolve(self.embedded_view); - }); - } else { - if (! this.view_type) - console.warn("view_type is not defined", this); - view_loaded_def = this.dataset._model.fields_view_get({ - "view_id": this.view_id, - "view_type": this.view_type, - "toolbar": !!this.options.sidebar, - "context": this.dataset.get_context(), - }); - } - return this.alive(view_loaded_def).then(function(r) { - self.fields_view = r; - // add css classes that reflect the (absence of) access rights - self.$el.addClass('oe_view') - .toggleClass('oe_cannot_create', !self.is_action_enabled('create')) - .toggleClass('oe_cannot_edit', !self.is_action_enabled('edit')) - .toggleClass('oe_cannot_delete', !self.is_action_enabled('delete')); - return $.when(self.view_loading(r)).then(function() { - self.trigger('view_loaded', r); - }); - }); - }, - view_loading: function(r) { - }, - set_default_options: function(options) { - this.options = options || {}; - _.defaults(this.options, { - // All possible views options should be defaulted here - $sidebar: null, - sidebar_id: null, - action: null, - action_views_ids: {} - }); + /** + * Triggers event 'view_loaded'. + * Views extending start() must call this.super() once they are ready. + * @return {Deferred} + */ + start: function() { + // add css classes that reflect the (absence of) access rights + this.$el.addClass('oe_view') + .toggleClass('oe_cannot_create', !this.is_action_enabled('create')) + .toggleClass('oe_cannot_edit', !this.is_action_enabled('edit')) + .toggleClass('oe_cannot_delete', !this.is_action_enabled('delete')); + return this._super().then(this.trigger.bind(this, 'view_loaded')); }, /** * Fetches and executes the action identified by ``action_data``. @@ -87,7 +59,7 @@ var View = Widget.extend({ * @param {String} [action_data.special=null] special action handlers (currently: only ``'cancel'``) * @param {String} [action_data.type='workflow'] the action type, if present, one of ``'object'``, ``'action'`` or ``'workflow'`` * @param {Object} [action_data.context=null] additional action context, to add to the current context - * @param {instance.web.DataSet} dataset a dataset object used to communicate with the server + * @param {DataSet} dataset a dataset object used to communicate with the server * @param {Object} [record_id] the identifier of the object on which the action is to be applied * @param {Function} on_closed callback to execute when dialog is closed or when the action does not generate any result (no new action) */ @@ -158,47 +130,16 @@ var View = Widget.extend({ return dataset.exec_workflow(record_id, action_data.name).then(handler); } }, - /** - * Directly set a view to use instead of calling fields_view_get. This method must - * be called before start(). When an embedded view is set, underlying implementations - * of instance.web.View must use the provided view instead of any other one. - * - * @param embedded_view A view. - */ - set_embedded_view: function(embedded_view) { - this.embedded_view = embedded_view; - }, do_show: function () { this._super(); core.bus.trigger('view_shown', this); }, - is_active: function () { - return this.ViewManager.active_view.controller === this; - }, - /** - * Wraps fn to only call it if the current view is the active one. If the - * current view is not active, doesn't call fn. - * - * fn can not return anything, as a non-call to fn can't return anything - * either - * - * @param {Function} fn function to wrap in the active guard - */ - guard_active: function (fn) { - var self = this; - return function () { - if (self.is_active()) { - fn.apply(self, arguments); - } - }; - }, do_push_state: function(state) { if (this.getParent() && this.getParent().do_push_state) { this.getParent().do_push_state(state); } }, do_load_state: function (state, warm) { - }, /** * This function should render the buttons of the view, set this.$buttons to |
