Odoo
Require Concept
Odoo
web framework come up with new concept of module loading which is
almost inherited from RequireJS.
Let
me describe how modules are loaded, how dependencies are calculated ?
Everything
else is similar in web framework but now It is more modular, each and
every component is reusable by just fetching/calling it using
require(Its a wrapper to load the object)
Previously
modules where loaded using namespace(same name given as module name
to JS namespace)
First
of all note that now onwards global object openerp is replaced with
odoo.
Now
onwards if you want to create any module or any widget you can simply
define it using odoo.define, lets have example of both style old
style as well as new style.
Old
Style: openerp.my_module = function(openerp) {
openerp.web.my_widget1
= openerp.web.wdiget.extend({
//your
widget stuff here
popup
= new openerp.web.FormPopup(...);
});
openerp.web.my_widget2
= openerp.web.wdiget.extend({
//your
widget stuff here
});
});
New
Style: odoo.define('openerp.my_module', function(require) {
popup
= require('form_popup') //Where form_popup is separately defined in
another file
web
= require('odoo_web');
web.my_widget2
= openerp.web.wdiget.extend({
//your
widget stuff here
});
});
No
doubt in both cases we can have re-usability but in later one we can
maintain small files for small features and can use that small
feature in another file by requiring it, code is more readable and
simpler.
Note
that, new style you need to define files in proper order because one
feature might depends on another and due to dependency issue you
module might not be loaded.
Lets
have a look how it works in background ?
we
having one main file boot.js, boot.js file having anonymous function
and it is in closure style which is called when file is loaded in
DOM, the responsibility of boot.js is to load module, this file is
the file which generates the concept of require method and
dependency.
It
creates global odoo object which having define method, now note that
all other files will have define function called where second
parameter will be callback function, whenever each file is loaded,
each file will call define method of odoo, now define method of odoo
global object checks for the arguments and second argument will have
function in which there will be other require calls.
Define
method checks for the require calls using Regular Expression, after
gathering all require calls it fetches those objects from services
object
Service
object is a object which is module's/object's pool.
Say
for example if I define one of my widget:
odoo.define('form.digital_signature',
function() {....});
Then
form.digital_signature is going to register in service pool
If
there is dependency missing then its not going to load that module,
if everything is fine, if it finds all dependent module are already
loaded in service object pool then it calls function which is second
parameter in define and also add that module/feature with name given
as a first argument in service pool, if one tries to register service
with same name twice then it will raise error that service with same
name is already registered.
There
are some core methods in boot.js, which you should go through:
define
-> Finds require call, generates dependency list, creates wrapper
of require
process_jobs
-> loads module and add that module in module/object service and
factories pool
init
-> initializes webclient
So
with this we can simply create small features and us it by calling it
another file using require('feature_name')
All
your generated module will generally return reference of your object
like example given below:
odoo.define('web.ajax',
function (require) {
"use
strict";
var
time = require('web.time');
var
Dialog = require('web.dialog');
time.date_to_utc...
var
my_dialog = new Dialog(....)
});
where
web.dialog is:
odoo.define('web.Dialog',
function (require) {
"use
strict";
var
Dialog = Widget.extend({
//your
dialog stuff
});
return
Dialog;
});
So
here web.dialog returns reference of Dialog and we can then use new
Dialog after calling var Dialog require('web.dialog');
Hope
this will help, feel free to raise your query by comments.
No comments:
Post a Comment