Javascript modulok¶
Az Odoo három különböző típusú javascript fájlt támogat:
plain javascript fájlok (nincs modulrendszer),
Odoo modulok (egyedi modulrendszer használatával),
Ahogy a eszközkezelési oldalon le van írva, az összes javascript fájl össze van csomagolva és a böngészőnek van kiszolgálva. Vegye figyelembe, hogy a natív javascript fájlokat az Odoo szerver dolgozza fel és Odoo egyedi modulokká alakítja át.
Röviden magyarázzuk el az egyes javascript fájltípusok mögötti célt. Az egyszerű javascript fájlokat csak külső könyvtárakhoz és néhány kis, specifikus alacsony szintű célra kell fenntartani. Minden új javascript fájlt a natív javascript modulrendszerben kell létrehozni. Az egyedi modulrendszer csak a régi, még nem konvertált fájlok esetében hasznos.
Egyszerű Javascript fájlok¶
Az egyszerű javascript fájlok tetszőleges tartalmat tartalmazhatnak. Javasolt az iife azonnal meghívott függvény végrehajtás stílus használata ilyen fájl írásakor:
(function () {
// some code here
let a = 1;
console.log(a);
})();
Az ilyen fájlok előnye, hogy elkerüljük a lokális változók kiszivárgását a globális térbe.
Nyilvánvaló, hogy az egyszerű javascript fájlok nem kínálják a modulrendszer előnyeit, ezért óvatosnak kell lenni a csomagban lévő sorrenddel (mivel a böngésző pontosan ebben a sorrendben fogja végrehajtani őket).
Megjegyzés
Az Odoo-ban minden külső könyvtár egyszerű javascript fájlként van betöltve.
Natív Javascript Modulok¶
Odoo javascript code uses the native javascript module system. This is simpler, and brings the benefits of a better developer experience with a better integration with the IDE.
Let us consider the following module, located in web/static/src/file_a.js:
import { someFunction } from "./file_b";
export function otherFunction(val) {
return someFunction(val + 3);
}
There is a very important point to know: by default Odoo transpiles files under
/static/src and /static/tests into Odoo modules.
This file will then be transpiled into an Odoo module that looks like this:
odoo.define('@web/file_a', ['@web/file_b'], function (require) {
'use strict';
let __exports = {};
const { someFunction } = require("@web/file_b");
__exports.otherFunction = function otherFunction(val) {
return someFunction(val + 3);
};
return __exports;
)};
So, as you can see, the transformation is basically adding odoo.define on top
and updating the import/export statements. This is an opt-out system, it’s possible
to tell the transpiler to ignore the file.
/** @odoo-module ignore **/
(function () {
const sum = (a, b) => a + b;
console.log(sum(1, 2));
)();
Note the comment in the first line: it describes that this file should be ignored.
In other folders, files aren’t transpiled by default, it is opt-in. Odoo will look at the first line of a JS file and check if it contains a comment with @odoo-module and without the tag ignore. If so, it will automatically be converted to an Odoo module.
/** @odoo-module **/
export function sum(a, b) {
return a + b;
}
Another important point is that the transpiled module has an official name:
@web/file_a. This is the actual name of the module. Every relative imports
will be converted as well. Every file located in an Odoo addon
some_addon/static/src/path/to/file.js will be assigned a name prefixed by the
addon name like this: @some_addon/path/to/file.
A relatív importok működnek, de csak akkor, ha a modulok ugyanabban az Odoo kiegészítőben vannak. Tehát képzeljük el, hogy a következő fájlstruktúrával rendelkezünk:
addons/
web/
static/
src/
file_a.js
file_b.js
stock/
static/
src/
file_c.js
A file_b fájl importálhatja a file_a fájlt így:
import {something} from `./file_a`;
De a file_c fájlnak a teljes nevet kell használnia:
import {something} from `@web/file_a`;
Aliasolt modulok¶
Mivel az Odoo modulok eltérő modul elnevezési mintát követnek, létezik egy rendszer, amely lehetővé teszi a zökkenőmentes átmenetet az új rendszer felé. Jelenleg, ha egy fájl modullá van konvertálva (és így követi az új elnevezési konvenciót), a projektben lévő más fájlok, amelyek még nem lettek ES6-szerű szintaxisra konvertálva, nem tudják igényelni a modult. Az aliasok itt vannak, hogy a régi neveket újakkal térképezzék fel egy kis proxy funkció létrehozásával. A modult ezután új és régi nevén is lehet hívni.
Ilyen alias hozzáadásához a fájl tetején található megjegyzés címkének így kell kinéznie:
/** @odoo-module alias=web.someName**/
import { someFunction } from './file_b';
export default function otherFunction(val) {
return someFunction(val + 3);
}
Ezután a lefordított modul létrehoz egy alias-t a kért névvel:
odoo.define(`web.someName`, ['@web/file_a'], function(require) {
return require('@web/file_a')[Symbol.for("default")];
});
The default behaviour of aliases is to re-export the default value of the
module they alias. This is because „classic” modules generally export a single
value which would be used directly, roughly matching the semantics of default
exports.
However it is also possible to delegate more directly, and follow the exact
behaviour of the aliased module:
/** @odoo-module alias=web.someName default=0**/
import { someFunction } from './file_b';
export function otherFunction(val) {
return someFunction(val + 3);
}
Ebben az esetben ez egy alias-t definiál pontosan az eredeti modul által exportált értékekkel:
odoo.define(`web.someName`, ["@web/file_a"], function(require) {
return require('@web/file_a');
});
Megjegyzés
Csak egy alias definiálható ezzel a módszerrel. Ha szüksége lenne egy másikra, hogy például három névvel hívhassa ugyanazt a modult, manuálisan kellene hozzáadnia egy proxy-t. Ez nem jó gyakorlat, és kerülendő, hacsak nincs más lehetőség.
Korlátozások¶
Teljesítmény okokból az Odoo nem használ teljes javascript elemzőt a natív modulok átalakítására. Ezért számos korlátozás van, beleértve, de nem kizárólagosan:
egy
importvagyexportkulcsszó előtt nem állhat nem szóköz karakter,egy több soros megjegyzés vagy szöveg nem tartalmazhat olyan sort, amely
importvagyexport-tal kezdődik// supported import X from "xxx"; export X; export default X; import X from "xxx"; /* * import X ... */ /* * export X */ // not supported var a= 1;import X from "xxx"; /* import X ... */
amikor egy objektumot exportál, nem tartalmazhat megjegyzést
// supported export { a as b, c, d, } export { a } from "./file_a" // not supported export { a as b, // this is a comment c, d, } export { a /* this is a comment */ } from "./file_a"
Az Odoo-nak szüksége van egy módszerre annak meghatározására, hogy egy modult egy útvonal (mint
./views/form_view) vagy egy név (mintweb.FormView) ír le. Ehhez egy heurisztikát kell használnia: ha van egy/a névben, azt útvonalnak tekinti. Ez azt jelenti, hogy az Odoo már nem támogatja igazán a/-t tartalmazó modulneveket.
As „classic” modules are not deprecated and there is currently no plan to remove them, you can and should keep using them if you encounter issues with, or are constrained by the limitations of, native modules. Both styles can coexist within the same Odoo addon.
Odoo Modul Rendszer¶
Az Odoo egy kis modulrendszert definiált (a addons/web/static/src/js/boot.js fájlban található, amelyet először be kell tölteni). Az Odoo modulrendszere, amelyet az AMD inspirált, azzal működik, hogy a define függvényt definiálja a globális odoo objektumon. Ezután minden javascript modult úgy definiálunk, hogy meghívjuk ezt a függvényt. Az Odoo keretrendszerben egy modul egy kódrészlet, amelyet a lehető leghamarabb végrehajtanak. Van egy neve és esetleg néhány függősége. Amikor a függőségei betöltődnek, a modul is betöltődik. A modul értéke ekkor a modult definiáló függvény visszatérési értéke.
Például így nézhet ki:
// in file a.js
odoo.define('module.A', [], function (require) {
"use strict";
var A = ...;
return A;
});
// in file b.js
odoo.define('module.B', ['module.A'], function (require) {
"use strict";
var A = require('module.A');
var B = ...; // something that involves A
return B;
});
Ha néhány függőség hiányzik/nem áll készen, akkor a modul egyszerűen nem töltődik be. Néhány másodperc múlva figyelmeztetés jelenik meg a konzolon.
Vegye figyelembe, hogy a körkörös függőségek nem támogatottak. Ez logikus, de azt jelenti, hogy óvatosnak kell lenni.
Egy modul definiálása¶
Az odoo.define metódus három argumentumot kap:
moduleName: a javascript modul neve. Egyedi karakterláncnak kell lennie. A konvenció az, hogy az odoo addon neve után egy specifikus leírás következik. Például aweb.Widgetegy modult ír le, amely awebaddonban van definiálva, és egyWidgetosztályt exportál (mivel az első betű nagybetűs)Ha a név nem egyedi, kivétel keletkezik, amely megjelenik a konzolon.
dependencies: It should be a list of strings, each corresponding to a javascript module. This describes the dependencies that are required to be loaded before the module is executed.finally, the last argument is a function which defines the module. Its return value is the value of the module, which may be passed to other modules requiring it.
odoo.define('module.Something', ['web.ajax'], function (require) { "use strict"; var ajax = require('web.ajax'); // some code here return something; });
Ha hiba történik, az naplózásra kerül (hibakeresési módban) a konzolon:
Hiányzó függőségek: Ezek a modulok nem jelennek meg az oldalon. Lehetséges, hogy a JavaScript fájl nincs az oldalon, vagy a modul neve helytelenSikertelen modulok: JavaScript hiba észlelveElutasított modulok: A modul elutasított Promise-t ad vissza. Ez (és a tőle függő modulok) nem töltődik be.Elutasított kapcsolt modulok: Modulok, amelyek egy elutasított modultól függenekNem betöltött modulok: Modulok, amelyek egy hiányzó vagy sikertelen modultól függenek