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

Odoo 16创建One2many自定义组件遇阻及数据访问问题求助

解决方案:Odoo One2many字段有序列表展示修复

问题1:AbstractField组件报错&_render未执行

问题原因

未指定组件支持的字段类型,Odoo将你的accordion_widget默认绑定到了text类型字段,但实际使用的是one2many类型字段,导致类型不匹配,触发"Missing widget"错误,且组件未正确初始化,_render方法无法执行。

修复代码

odoo.define('your_module.accordion_widget', function (require) {
    "use strict";

    const AbstractField = require('web.AbstractField');
    const fieldRegistry = require('web.field_registry');

    const AccordionWidget = AbstractField.extend({
        // 明确指定支持one2many类型字段
        supportedFieldTypes: ['one2many'],
        _render: function () {
            // 从record中读取One2many字段数据
            const records = this.record.data[this.name] || [];
            // 生成有序列表DOM
            const $ol = $('<ol>');
            records.forEach(record => {
                // 替换为你需要展示的字段(例:name字段)
                $ol.append($(`<li>${record.data.name}</li>`));
            });
            this.$el.html($ol);
        },
    });

    fieldRegistry.add('accordion_widget', AccordionWidget);
    return AccordionWidget;
});

XML使用示例

<field name="field_ids" widget="accordion_widget"/>

问题2:X2ManyField组件无法访问field_ids数据

问题原因

X2ManyField的数据加载有异步逻辑,若未等待数据加载完成或使用了错误的数据源获取方式,会导致无法读取关联记录。

修复代码

odoo.define('your_module.x2many_ol_widget', function (require) {
    "use strict";

    const X2ManyField = require('web.X2ManyField');
    const fieldRegistry = require('web.field_registry');

    const X2ManyOLWidget = X2ManyField.extend({
        // 禁用默认渲染器,自定义渲染逻辑
        customRenderer: true,
        // 等待关联字段数据加载完成
        willStart: function () {
            return this._super.apply(this, arguments).then(() => {
                // 确保One2many字段数据被加载
                return this.record.load(this.name);
            });
        },
        _render: function () {
            // 正确获取One2many记录集合
            const records = this.record.data[this.name] || [];
            const $ol = $('<ol>');
            records.forEach(record => {
                $ol.append($(`<li>${record.data.name}</li>`));
            });
            this.$el.html($ol);
        },
        // 监听数据更新,重新渲染
        _updateValue: function (value) {
            this._super(value);
            this._render();
        },
    });

    fieldRegistry.add('x2many_ol_widget', X2ManyOLWidget);
    return X2ManyOLWidget;
});

XML使用示例

<field name="field_ids" widget="x2many_ol_widget"/>

两种方案对比

  • AbstractField方案:轻量简洁,适合仅需展示的场景,无需处理X2ManyField的复杂交互逻辑(如增删记录按钮)。
  • X2ManyField方案:可复用X2ManyField的底层数据管理逻辑,若后续需要添加编辑、删除功能,扩展更便捷。

内容的提问来源于stack exchange,提问作者Jacky Supit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:33:12