一、介绍
odoo的前端javascript框架是web模块提供的一组功能/组件,旨在帮助用户搭建odoo网页端程序。
web客户端最初是一个使用自定义类和小部件系统开发的应用程序,但现在它正转而使用本机javascript类和owl组件系统,这就解释了为什么现在ODOO里两者并存。
从更新层面讲,Web 客户端是一个单页应用程序(single-page):它不需要在用户每次执行操作时都向服务器请求一个完整的页面。相反,它只请求它需要的内容,然后相应地替换/更新当前屏幕。此外,它管理 url 以使其与当前状态保持同步。
javascript 框架(全部或部分)也用于其他情况,例如 Odoo 网站或销售点。此参考主要集中在 Web 客户端上。
注:如果可能,所有新的开发都应该在 Owl 中完成!
代码结构:
目录web/static/src包含所有的JA库(包括CSS和templates模板),目录结构:
core/ 大多数的低级功能
fields/ 所有的字段组件
views/ 所有的视图组件 (form, list, …)
search/ control panel 搜索及控制面板
webclient/ 网页客户端特定代码: navbar, user menu, action service, …
The web/static/src 是根目录. 里面的每项内容都可以通过 @web 前缀引用. 例如:
import { memoize } from "@web/core/utils/functions";
二、Web客户端架构
如上所述,Web 客户端是一个 owl 应用程序。这是其模板的稍微简化的版本:
<t t-name="web.WebClient" owl="1">
<body class="o_web_client">
<NavBar/>
<ActionContainer/>
<MainComponentsContainer/>
</body>
</t>
正如我们所见,它基本上是封装了navbar,action及一些附加的组件,“ActionContainer”是一个高级组件,显示当前的动作控制器,管理action是其工作的重要组成部分,将所有活跃的action的堆栈(用面包屑中表示)保存在内存中,并协调每次更改。
/** @odoo-module **/
import { ActionDialog } from "./action_dialog";
const { Component, tags } = owl;
// -----------------------------------------------------------------------------
// ActionContainer (Component)
// -----------------------------------------------------------------------------
export class ActionContainer extends Component {
setup() {
this.info = {};
this.env.bus.on("ACTION_MANAGER:UPDATE", this, (info) => {
this.info = info;
this.render();
});
}
__destroy() {
this.env.bus.off("ACTION_MANAGER:UPDATE", this);
super.__destroy();
}
}
ActionContainer.components = { ActionDialog };
ActionContainer.template = tags.xml`
<t t-name="web.ActionContainer">
<div class="o_action_manager">
<t t-if="info.Component" t-component="info.Component" t-props="info.componentProps" t-key="info.id"/>
</div>
</t>`;
另一个组件是MainComponentsContainer:它只是一个显示在 main_components注册表中注册的所有组件的组件。以实现扩展 Web 客户端。
三、环境
作为一个 Owl 应用程序,Odoo Web 客户端定义了自己的环境(组件可以使用 访问它this.env)。以下是 Odoo 添加到共享env对象的描述:
key | value |
---|---|
qweb | Owl 所需(包含所有模板) |
bus | 主总线,用于协调一些通用事件 |
services | 所有已部署的服务(通常应该使用useService钩子访问) |
debug | 调试,如果非空,则 Web 客户端处于调试模式 |
_t | 翻译功能 |
isSmall | 布尔值。如果为 true,则 Web 客户端当前处于移动模式(屏幕宽度 <= 767px) |
例如,要翻译组件中的字符串(注意:templates是自动翻译的,因此在这种情况下不需要特定操作),可以这样做:
const someString = this.env._t(‘some text’);
四、建设模块
大多数web客户端由如下几部分组成:1、注册器 2、服务 3、组件 4、钩子
1、注册表(Registries)
注册表是一个简单的键/值映射,用于存储某种特定类型的对象。它们是 UI 可扩展性的重要组成部分:一旦注册了某个对象,Web 客户端的其余部分就可以使用它。例如,字段注册表包含可在视图中使用的所有字段组件(或小部件)。
import { registry } from "./core/registry";
class MyFieldChar extends owl.Component {
// some code
}
registry.category("fields").add("my_field_char", MyFieldChar);
注意,我们从导入主注册表@web/core/registry然后打开子注册表fields。
2、服务
服务是提供功能的长生命周期代码片段。它对于组件和其他服务非常重要。
此外,服务可以声明一组依赖项,从这个意义上讲,服务基本上是一个DI(依赖注入)系统,依赖注入是实现控制反转的一种设计方法,例如, notification 服务提供途径去显示一条 notification, 或者如 rpc 服务是执行对Odoo服务器的请求的正确方式。
下面的例子建立了一简单的服务,每5秒钟显示一个notification :
import { registry } from "./core/registry";
const myService = {
dependencies: ["notification"],
start(env, { notification }) {
let counter = 1;
setInterval(() => {
notification.add(`Tick Tock ${counter++}`);
}, 5000);
}
};
serviceRegistry.add("myService", myService);
中亿丰数字 姜振建 15954039008