You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 11:33:13