概要
在odoo16里面,网站前端的UI组件基本都是通过publicWidget.registry
对象的属性来注册的,在odoo中也可称为小部件widget。注册新的组件,基本都是在Widget上进行扩展。
场景介绍
场景一:创建一个新的的组件DemoA。
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="your_class" name="Demo A">
<t t-call="website.layout">
<div>
这是组件视图
</div>
</t>
</template>
</odoo>
/** @odoo-module */
import publicWidget from 'web.public.widget';
publicWidget.registry.DemoAForm = publicWidget.Widget.extend({
selector: '#your_class', //视图选择器,对应你的视图组件
init: function () {
this._super.apply(this, arguments);
console.log('打印测试是否可以成功挂载')
},
demo_one(){
console.log('这是原来的demo_one')
},
});
export const DemoAForm = publicWidget.registry.DemoAForm ;
'assets': {
# 注意引入的键名
"web.assets_frontend": [
'demo/static/src/js/demo_a.js',
],
},
注意:视图一定要在odoo的布局上面。(website.layout)
场景二:已存在组件DemoA,现在要对组件进行原方法修改。
/** @odoo-module */
import DemoAForm from "demo_a.demo_a";
var _t = core._t;
DemoAForm.include({
init: function () {
this._super.apply(this, arguments);
console.log('不管继承还是覆盖,建议都加上构造函数')
},
demo_one(){
//执行原来方法逻辑
this._super(...arguments);
//执行新逻辑
console.log('这是新的的demo_one')
},
})
场景三:已存在组件DemoA,现在要对组件进行覆盖原方法。
/** @odoo-module */
import DemoAForm from "demo_a.demo_a";
var _t = core._t;
DemoAForm.include({
init: function () {
this._super.apply(this, arguments);
console.log('不管继承还是覆盖,建议都加上构造函数')
},
demo_one(){
//方法名相同即可覆盖(前提不要_super)
console.log('这是新的的demo_one')
},
})
场景四:已存在组件DemoA,现在要对组件进行增加新方法。
/** @odoo-module */
import DemoAForm from "demo_a.demo_a";
DemoAForm.include({
events: Object.assign({}, DemoAForm.prototype.events, {
"click .demo_b": "_onClickDemoB" //视图需要有对应的选择器
}),
init: function () {
this._super.apply(this, arguments);
console.log('不管继承还是覆盖,建议都加上构造函数')
},
_onClickDemoB(){
console.log('这是新的方法,可以是事件方法,可以是封装的方法函数')
},
})
场景五:已存在组件DemoA,现在需要使用DemoA整套逻辑新写一个新组件,但是又不能影响原来的组件逻辑。
/** @odoo-module */
import DemoAForm from "demo_a.demo_a";
publicWidget.registry.DemoB = DemoAForm.extend({
selector: '#your_class_b',
events: _.extend({}, DemoAForm.prototype.events, {
"click .demo_c": "_onClickDemoC" //视图需要有对应的选择器
}),
init: function () {
this._super.apply(this, arguments);
},
})
export const DemoBForm = publicWidget.registry.DemoB ;
注意: 如果不填写选择的视图,则默认跟DemoAForm同一个,这样容易导致方法同步问题的出现,因为这样方法会被调用两次。
小结
首先,这里建议用ES6的写法。其次,明白自己的业务功能需求,如二开则基本选择include进行原功能修改,否则很容易出现方法同步问题。如果是新视图开发,则自己把握住功能的复用性进行组件新注册/继承开发。