Odoo 17自定义组件获取depends属性及监听字段变化问题
解决Odoo 17自定义Widget获取
depends属性及监听字段变化的问题 问题根源
Odoo不会自动将XML字段标签上的自定义depends属性传递到Widget的props中,因为原生depends是视图层面的属性,仅用于触发视图整体更新。要让Widget获取到依赖字段列表,需通过options属性传递自定义参数;同时自定义字段Widget需继承Odoo提供的FieldWidget基类,才能获取到record、fieldInfo等核心props。
步骤1:修改XML字段引用
将依赖字段列表放到options中,确保Widget能读取到:
<field name="my_field" widget="my_widget" options='{"depends": ["field_a", "field_b"]}' />
步骤2:调整Widget组件代码
继承FieldWidget基类,调用父类setup方法,从props.options中获取依赖字段,并实现字段监听:
import { FieldWidget } from "@web/views/fields/field_widget"; import { useWatch, onWillUnmount } from "@odoo/owl"; export class MyWidgetComponent extends FieldWidget { setup() { // 必须调用父类setup,初始化FieldWidget的核心逻辑 super.setup(); // 从options中获取依赖字段列表 this.depends = this.props.options.depends || []; console.log("依赖字段列表:", this.depends); // 方法1:使用useWatch监听字段变化(推荐) this.setupWatchers(); // 方法2:监听record的change事件(备选) // this.setupRecordListeners(); } setupWatchers() { const { record } = this.props; // 监听依赖字段的变化 useWatch(() => { // 当field_a/field_b变化时,执行更新逻辑 const fieldAVal = record.data.field_a; const fieldBVal = record.data.field_b; // 这里更新组件内部值 this.updateComponentValues(fieldAVal, fieldBVal); }, this.depends.map(field => `record.data.${field}`)); } setupRecordListeners() { const { record } = this.props; const onChange = (event) => { if (this.depends.includes(event.target)) { const fieldAVal = record.data.field_a; const fieldBVal = record.data.field_b; this.updateComponentValues(fieldAVal, fieldBVal); } }; // 绑定监听事件 record.on("change", this, onChange); // 组件销毁时移除监听,避免内存泄漏 onWillUnmount(() => { record.off("change", this, onChange); }); } updateComponentValues(valA, valB) { // 这里实现你的组件内部值更新逻辑 console.log("字段更新:", valA, valB); } }
关键说明
- 继承
FieldWidget是核心:它会自动注入record、fieldInfo等Odoo字段组件的必备props,基础Component无法获取这些内容。 options是传递自定义参数的标准方式:Odoo会将options中的JSON内容解析后传递到Widget的props.options中。- 两种监听方式的区别:
useWatch是Owl的官方钩子,写法更简洁;record.change事件更灵活,适合复杂场景。
内容的提问来源于stack exchange,提问作者Felix Daniel Coca Calvimontes
相关产品推荐
相关产品推荐

