diff options
| author | Géry Debongnie <ged@odoo.com> | 2015-03-09 16:34:27 +0100 |
|---|---|---|
| committer | Géry Debongnie <ged@odoo.com> | 2015-03-18 09:01:49 +0100 |
| commit | e8a00bc50da435d3859118ca127d20a2eb9a0cab (patch) | |
| tree | 039f6ec40b37392e76c8830a8e518ac40f7e7fec /addons/web/static/src/js/framework/model.js | |
| parent | 9036084f065c7aca3b2199903f4da67db3501ba7 (diff) | |
[REF] web: add module system to the web client
This commit introduces a new module system for the javascript code.
Instead of using global (namespaced) variables everywhere (like
openerp.web.whatever, ...), each file declare one (or more) module
with its dependencies. Each module will be loaded after its
dependencies, and will be given a reference to the return values.
This change is a massive departure from the way the client worked
previously. It will sadly break some/most history, but I am sure that
the future git ecosystem will allow you to easily browse the history
past this revision (one can dream).
This commit feature:
* main namespace is now odoo instead of openerp
* a way to define modules and dependencies (inspired by requirejs)
* many files have been splitted in simpler subfiles
* basic support for debugging in odoo.__DEBUG__
* no global variable (i.e. nothing in window.openerp)
* many bug fixes, many new bugs
Future vision: this modularization should simplify future code
development, simplify debugging and will allow a serious testing effort
Diffstat (limited to 'addons/web/static/src/js/framework/model.js')
| -rw-r--r-- | addons/web/static/src/js/framework/model.js | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/addons/web/static/src/js/framework/model.js b/addons/web/static/src/js/framework/model.js new file mode 100644 index 00000000000..f1a1555fd6f --- /dev/null +++ b/addons/web/static/src/js/framework/model.js @@ -0,0 +1,191 @@ +odoo.define('web.Model', ['web.Class', 'web.session', 'web.utils'], function (require) { +"use strict"; + +var Class = require('web.Class'); +var session = require('web.session'); +var utils = require('web.utils'); + +var Model = Class.extend({ + /** + new openerp.web.Model([session,] model_name[, context[, domain]]) + + @constructs instance.web.Model + @extends instance.web.Class + + @param {openerp.web.Session} [session] The session object used to communicate with + the server. + @param {String} model_name name of the OpenERP model this object is bound to + @param {Object} [context] + @param {Array} [domain] + */ + init: function(name, context, domain) { + this.name = name; + this._context = context || {}; + this._domain = domain || []; + }, + /** + * @deprecated does not allow to specify kwargs, directly use call() instead + */ + get_func: function (method_name) { + var self = this; + return function () { + return self.call(method_name, _.toArray(arguments)); + }; + }, + /** + * Call a method (over RPC) on the bound OpenERP model. + * + * @param {String} method name of the method to call + * @param {Array} [args] positional arguments + * @param {Object} [kwargs] keyword arguments + * @param {Object} [options] additional options for the rpc() method + * @returns {jQuery.Deferred<>} call result + */ + call: function (method, args, kwargs, options) { + args = args || []; + kwargs = kwargs || {}; + if (!_.isArray(args)) { + // call(method, kwargs) + kwargs = args; + args = []; + } + var call_kw = '/web/dataset/call_kw/' + this.name + '/' + method; + return session.rpc(call_kw, { + model: this.name, + method: method, + args: args, + kwargs: kwargs + }, options); + }, + /** + * Executes a signal on the designated workflow, on the bound OpenERP model + * + * @param {Number} id workflow identifier + * @param {String} signal signal to trigger on the workflow + */ + exec_workflow: function (id, signal) { + return session.rpc('/web/dataset/exec_workflow', { + model: this.name, + id: id, + signal: signal + }); + }, + /** + * Performs a fields_view_get and apply postprocessing. + * return a {$.Deferred} resolved with the fvg + * + * @param {Object} args + * @param {String|Object} args.model instance.web.Model instance or string repr of the model + * @param {Object} [args.context] context if args.model is a string + * @param {Number} [args.view_id] id of the view to be loaded, default view if null + * @param {String} [args.view_type] type of view to be loaded if view_id is null + * @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); + }); + }); + return fvg; + }); + } +}); + +return Model; +}); + +odoo.define('web.DataModel', ['web.data', 'web.Model', 'web.pyeval', 'web.session'], function (require) { +"use strict"; + +var data = require('web.data'); +var Model = require('web.Model'); +var pyeval = require('web.pyeval'); +var session = require('web.session'); + +Model.include({ + /** + * Fetches a Query instance bound to this model, for searching + * + * @param {Array<String>} [fields] fields to ultimately fetch during the search + * @returns {instance.web.Query} + */ + query: function (fields) { + return new data.Query(this, fields); + }, + /** + * Fetches the model's domain, combined with the provided domain if any + * + * @param {Array} [domain] to combine with the model's internal domain + * @returns {instance.web.CompoundDomain} The model's internal domain, or the AND-ed union of the model's internal domain and the provided domain + */ + domain: function (domain) { + if (!domain) { return this._domain; } + return new data.CompoundDomain(this._domain, domain); + }, + /** + * Fetches the combination of the user's context and the domain context, + * combined with the provided context if any + * + * @param {Object} [context] to combine with the model's internal context + * @returns {instance.web.CompoundContext} The union of the user's context and the model's internal context, as well as the provided context if any. In that order. + */ + context: function (context) { + return new data.CompoundContext(session.user_context, this._context, context || {}); + }, + /** + * Call a method (over RPC) on the bound OpenERP model. + * + * @param {String} method name of the method to call + * @param {Array} [args] positional arguments + * @param {Object} [kwargs] keyword arguments + * @param {Object} [options] additional options for the rpc() method + * @returns {jQuery.Deferred<>} call result + */ + call: function (method, args, kwargs, options) { + args = args || []; + kwargs = kwargs || {}; + if (!_.isArray(args)) { + // call(method, kwargs) + kwargs = args; + args = []; + } + pyeval.ensure_evaluated(args, kwargs); + var call_kw = '/web/dataset/call_kw/' + this.name + '/' + method; + return session.rpc(call_kw, { + model: this.name, + method: method, + args: args, + kwargs: kwargs + }, options); + }, + call_button: function (method, args) { + pyeval.ensure_evaluated(args, {}); + return session.rpc('/web/dataset/call_button', { + model: this.name, + method: method, + // Should not be necessary anymore. Integrate remote in this? + domain_id: null, + context_id: args.length - 1, + args: args || [] + }); + }, + +}); + +}); |
