Odoo 15实战开发之OWL视图开发

Odoo Alan 3年前 (2021-09-10) 11560次浏览 7个评论 扫描二维码

什么是OWL 

OWL是 Odoo 在版本14中一个大动作,是Odoo Web Library的缩写,简单的说是一套前端开发框架。官方总结主要特性有:

  • 声明式的组件系统
  • 基于钩子的响应式系统
  • 默认为并发模式
  • 存储和前端路由

听起来有些类似流行的 Web 框架 Angular、Vue、React等,那么 Odoo 为什么还要重造轮子,请收看《Odoo 有话说》

Odoo 15实战开发之OWL视图开发

上图为10月6日Odoo 15大会中给出的OWL修订后的路线图,可以看到在 v15中并没有完全弃用老的前端代码,但在 Odoo 16中将会彻底切换为 OWL。

以下窃取一个示例来说明 OWL 的优势:

在界面中添加两个按钮,在点击操作时一个进行累加,另一个做清除将值重置为0,实时的结果显示在一个 div 中,普通HTML 的实现方式为:

接下来就写编写 Javascript 来实现相应的逻辑了:

对于前端朋友这些简直是家常便饭了,这只是一个很小的例子,如果逻辑更为复杂,代码量可想而知。下面是使用现代框架OWL进行实现的代码:

好像并没有变简单,重点在JS 代码:

怎么样?是不是很丝滑?框架为我们处理了事件监听、DOM 操作这个麻烦事,让代码看起来也非常之简洁。

闲言少絮,我们直接进入实战,看看来 Odoo 中如何进行实操。

准备工作

Odoo 14开始内置有OWL,因此不需要再进行额外的安装。首先我们需要新建一个模块来进行 OWL 开发的演示,基本目录结构如下:

声明文件示例:

添加组件

OWL的通过定义Component类的方式来进行编码,可以看成是 web 组件。组件中有模板、数据绑定及子组件。

我们都熟知在 HTML中有 headerdivspantextarea等标签。在 OWL 中,我们可以自己创造这些标签,比如在项目管理系统中可以使用project 和 task标签来展示信息,或是在系统中使用contact标签来显示用户或客户。本例中我们创建一个组件在销售订单的客户信息下展示其订单历史信息。新建组件需要经过2步:

1. 创建并注册js类

新组件位于static/src/js/components/下,命名为PartnerOrderSummary.js,内容如下:

Odoo 14

在Odoo中所有的 Javascript 代码通过继承assets模板并添加script标签来进行注册。本例我们在模块的根目录下创建assets.xml文件:

然后在__manifest__.py文件中添加assets.xml

Odoo 15

Odoo 15中以上代码就行不通了,会出现ValueError: External ID not found in the system: web.assets_backend这样的报错,这是在为 Odoo 15开发模块时所遇到的第一个坑。

注意:Odoo 15对于前端中JS文件及模板文件等的注册进行了较大的调整,将这些资源类的注册统一纳入到了声明文件的 assets 下,有web.assets_backend、web.assets_frontend、web.assets_common、web.assets_qweb等,下面注册小部件时就会使用到web.assets_qweb。

2. 为组件创建template xml文件

紧接着我们要创建一个XML模板。读者可能已经注意到在前面的代码中我们添加过一个template属性:

这里template 就是XML模板的名称。为方便管理,我们将模板文件放到 JS 的相同目录下,即static/src/js/components/PartnerOrderSummary.xml

有关xml:space=”preserve”更多的解释可参见Understanding xml:space中的说明,简单地说就是保留节点中的空格,多行时每一行需要用标签包裹。

类似JS 类,我们也需要注册这一模板文件。注册方法是在__manifest__.py文件中添加一个qweb配置:

Odoo 15

Odoo 14

在销售订单中显示我们的组件

现在我们已经开了一个显示一些文本的小模块,那么如何在销售订单的表单视图中显示它呢?

1. 修改模块的依赖

首先要在模块声明文件中添加对sales模块的依赖:

2. 重载表单渲染器挂载组件

更新模块来确保Sales已安装,接下来就将组件添加到销售订单的表单中了。

有很多种实现的方式,这里采用最简单的页面加载时挂载的方式。

我们需要修改 js 文件来扩展Odoo内核的表单渲染器,让其查找特定的html class并自动挂载到该元素中。

这里包含了比较多的知识,简单地说就是我们对带有o_partner_order_summary的元素挂载所开发的OWL组件。只需要通过下面这样就可以将组件挂载到指定的对象元素上:

3. 在销售订单的表单中添加一个div

我们在模块的根目录下创建一个views.xml文件用于重载销售订单的视图,添加我们的div。

相应地我们需要修改__manifest__.py文件:

美化小部件

此时更新模块就可以看到新增的模块了,下面我们做进一步的美化。

Odoo 15实战开发之OWL视图开发

1. 设计小部件 

先使用 mock 数据来调整样式。这里使用的不是真实数据,但可以看到最终的效果。推荐将 css 放到独立的文件中。

Odoo 15实战开发之OWL视图开发

2. 数据对接

最后就是要对接真实的数据。OWL通过state对象来跟踪所有的数据,因此我们需要在构造时添加partner属性并设置数据。

在表单视图渲染时会初始化该组件。这样我们可以获取获取partner信息并将其传递给构造函数:

 

以上代码中首先我们在页面中查找包含o_partner_order_summary的元素。然后对后端进行rpc调用获取partner数据并将其关联至当前订单(使用this.state.data来表示当前记录)。返回数据后挂载至组件中。

现在,我们可以在XML视图中通过变量partner来使用partner记录中的数据:

这个视图会将运行t-语句、拉取真实数据填充到视图中。最简单的是使用t-esc将数据直接打印到 div 标签中。可以在属性名前添加t-attf-来修改具体的属性,然后在该字符串中访问变量。

例如,可以像下面这样显示图片:

或像下面这样显示城市和邮编:

此时更新模块就可以看到我们的自定义小部件了:

Odoo 15实战开发之OWL视图开发

参考资料:

后记

本文是Alan 在做的一个尝试,之前已表明过正常情况下不会再翻译《开发指南》和《手册》,其中有版权的考虑,也有对社区发展阶段的判断。所以准备出一些集锦文章,内容参考Odoo Mates, Cybrosys、Greg Moss和Yenthe Van Ginneken等视频、文章,同时结合官方文档。未来有机会再整理一些更贴合实战的文章或视频。

关于Odoo 15,粗略看来对前端进行了比较大的调整,所以可能很多插件都需要做比较大的修改才能兼容。文章更多是做一种探讨和研究,线上使用大家还是再等半年以上吧!

 

喜欢 (40)
[]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(7)个小伙伴在吐槽
  1. Error: Template owl_demo.PartnerOrderSummary does not exist
    2022-06-16 14:32 回复
  2. 请教博主,odoo15在钉钉手机端打开出现空白(在钉钉里登录odoo客户端之后就进入空白页面),问题出在哪呢?是最新版的qweb和钉钉内置浏览器不兼容吗?被这个问题困扰,且有多人反馈有这种情况,还请楼主指教。odoo14就没这个问题。
    forest2022-06-09 10:43 回复
  3. 佩服佩服
    杨仙僧2021-11-02 17:51 回复
  4. 感谢博主,引导入门!!!!
    lgj132021-10-14 11:24 回复
  5. 对社区发展阶段的判断 :shock: 是不看好未来发展?还是?
    LittlePanger2021-10-12 15:11 回复
  6. well done
    fancn21th2021-09-16 10:31 回复
  7. 学不动了呀
    厉风行2021-09-13 22:12 回复