owl是odoo14的前端新事物,主要是用mvvm思想及type script标准重构前端。
在odoo14的前端框架中,现在还是以 widget与owl混用的方式。我们经常要对前端界面做一定优化,这种优化是基于odoo原生的,所以使用继承是必不可少的。
比如我们的superbar,ztree等组件,会对m2o和搜索进行优化。 而在odoo14中,搜索组件改由control_panel实现并已经全部用owl重构,这时我们就要进行继承开发处理,保证与odoo14的原生兼容及第三方兼容。同时优雅实现需求。
此文章源于 odoo14刚发布后,我们为了进行应用升级遇到的问题,最终实现的模块是 基于 odoo14的 superbar,即适应中国化的树状搜索导航栏。
可以在官方应用市场获取: app_web_superbar
下面说下实现
目标:搜索优化,实现更方便的搜索树
通过原生代码分析,主要是 web模块,在odoo14中,搜索相关的全部用owl方式进行了重构,在 ControlPanel 这个owl组件中,我们要进行:
- 前端处理方法patch,owl事件的super继承处理
- 前端数据源新class继承
- 前端界面的优化,template的继承处理
- 前端界面的优化,样式的处理
前端处理方法patch,owl事件的super继承处理
主要是方法重构,同时 super下上级方法。直接上代码
odoo.define('app_web_superbar.Superbar', function (require) { //方式一:参考 document 模块的 owl 继承,整体思路改变,做一个新的 SuperBar -> SearchPanel,然后在 abstract_view视图改其 SearchPanel=appSearchPanel //方式一测试正常,如下 // class Superbar extends SearchPanel { // constructor() { // super(...arguments); // console.log('test owl patch'); // alert('test owl patch'); // } // }; // return Superbar; //方式二:patch 原 SearchPanel,参考 mail, activity_renderer.js,暂时不知how "use strict"; const { device } = require("web.config"); const { Component } = owl; const SearchPanel = require("web/static/src/js/views/search_panel.js"); var SuperbarToggle = require('app_web_superbar.SuperbarToggle'); class Superbar extends SearchPanel { constructor() { super(...arguments); console.log('test owl patch extension'); } mounted() { super.mounted(...arguments); if (this.SuperbarToggle) this.SuperbarToggle.destroy(); setTimeout(function () { this.SuperbarToggle = new SuperbarToggle(this); let $node = this.$.find('div.o_cp_top'); this.SuperbarToggle.prependTo($node); }, 100); } }; Superbar.modelExtension = "Superbar"; Superbar.defaultProps = Object.assign({}, SearchPanel.defaultProps, {}); Superbar.props = Object.assign({}, SearchPanel.props, {}); if (!device.isMobile) { Superbar.template = "app.Superbar"; } return Superbar; });
前端数据进行优化,owl的数据源处理
主要是数据处理,这个现在不是patch原来数据源的方式,而是采用new一个model,这个model是旧model的extension的方式。这里会比较特殊,一定不能按odoo13的 include再super的方式。
odoo.define("app_web_superbar.SuperbarModelExtension", function (require) { "use strict"; const ActionModel = require("web/static/src/js/views/action_model.js"); const SearchPanelModelExtension = require("web/static/src/js/views/search_panel_model_extension.js"); class SuperbarModelExtension extends SearchPanelModelExtension { toggleCategoryValue(sectionId, valueId) { super.toggleCategoryValue(...arguments); console.log('patch toggleCategoryValue'); // 增加额外处理 } } ActionModel.registry.add("Superbar", SuperbarModelExtension, 30); return SuperbarModelExtension; });
前端界面的优化,template的继承处理
主要是视图继承,注意是 template的继承,这里我们可以看出,odoo14在template的继承上更方便了,从原来的jquery找节点方式进化到了与后台xml视图同样的 xpath方式,更为统一。
<!--owl 处理继承继承--> <t t-name="app.Superbar" t-inherit="web.SearchPanel" t-inherit-mode="primary" owl="1"> <!--改图标--> <!--All改为标头的 x --> <xpath expr="//header[hasclass('o_search_panel_section_header')]" position="replace"> <header class="o_search_panel_section_header text-uppercase"> <i t-attf-class="fa {{ section.icon }} o_search_panel_section_icon mr-2" t-att-style="section.color and ('color: ' + section.color)" t-att-data-origin-icon="section.icon" /> <b t-esc="section.description"/> <em t-att-class="'o_search_panel_category_value' + (!section.activeValueId ? ' o_hidden' : '')" t-att-data-category-id="section.id"> <button class="o_search_panel_section_clear btn btn-sm btn-default fa fa-lg fa-times-circle" type="button" t-att-data-field-name="section.fieldName" t-att-data-category-id="section.id" title="Show All Data" t-on-click="_toggleCategory(section, {childrenIds:[]})"/> </em> </header> </xpath> <xpath expr="//*[@t-call='web.SearchPanel.Category']" position="attributes"> <attribute name="t-call">app.Superbar.Category</attribute> </xpath> </t>
前端界面的优化,样式的处理
这个基本与odoo13一样,处理好scss就可以了,具体基础的css3知识足够。