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

Odoo技术问题:打开表单视图并在关闭时获取可用返回值

Odoo表单视图关闭时获取返回值的实现方案

可行性说明

这个需求完全可行,Odoo的前端OWL框架与后端RPC机制支持视图间的数据传递,通过自定义动作、前端事件监听或弹窗组件即可实现。


方案一:弹窗式表单视图(推荐)

适合临时创建/编辑数据并返回结果的场景,通过弹窗触发表单,关闭时传递数据。

1. 后端定义弹窗动作

在触发弹窗的模型中添加方法,返回弹窗配置:

from odoo import models, fields, api

class YourSourceModel(models.Model):
    _name = 'your.source.model'

    def action_open_popup_form(self):
        return {
            'name': '填写目标数据',
            'type': 'ir.actions.act_window',
            'res_model': 'target.data.model',  # 表单对应的目标模型
            'view_mode': 'form',
            'target': 'new',  # 弹窗模式
            'context': {
                'default_related_field': self.source_field,  # 传递默认值到弹窗
            }
        }

2. 前端监听弹窗关闭事件

在源模型的前端JS文件中,监听弹窗关闭时的事件并处理返回数据:

/** @odoo-module */

import { registry } from "@web/core/registry";
import { formView } from "@web/views/form/form_view";

registry.category("views").add("your_source_model_form", {
    ...formView,
    setup() {
        super.setup();
        // 监听弹窗数据返回事件
        this.env.bus.on('popup_data_return', this, this.handleReturnData);
    },
    handleReturnData(data) {
        // 处理返回的数据,示例:更新当前视图字段
        this.model.root.data.returned_field = data.target_field;
        // 保存当前记录
        this.model.root.save();
    },
});

3. 弹窗表单触发返回事件

在目标模型中重写保存方法,通过bus发送返回数据:

class TargetDataModel(models.Model):
    _name = 'target.data.model'

    def write(self, vals):
        res = super().write(vals)
        // 向前端发送数据返回事件
        self.env['bus.bus']._sendone(self.env.user.partner_id, 'popup_data_return', {
            'id': self.id,
            'target_field': self.your_field,
        })
        return res

    def create(self, vals):
        record = super().create(vals)
        self.env['bus.bus']._sendone(self.env.user.partner_id, 'popup_data_return', {
            'id': record.id,
            'target_field': record.your_field,
        })
        return record

方案二:普通表单视图的返回逻辑

如果使用非弹窗的普通表单视图,可通过修改关闭按钮行为实现数据返回:

1. 自定义表单关闭按钮

在目标模型的XML视图中重写关闭按钮:

<record id="target_data_form_view_custom" model="ir.ui.view">
    <field name="name">target.data.form.view.custom</field>
    <field name="model">target.data.model</field>
    <field name="inherit_id" ref="target_data_form_view"/>
    <field name="arch" type="xml">
        <xpath expr="//button[@name='action_close']" position="replace">
            <button name="action_close_and_return" string="关闭并返回" type="object" class="btn-secondary"/>
        </xpath>
    </field>
</record>

2. 后端定义返回方法

在目标模型中添加关闭回调方法,传递返回数据:

class TargetDataModel(models.Model):
    _name = 'target.data.model'

    def action_close_and_return(self):
        // 组装返回数据
        return_data = {
            'id': self.id,
            'field1': self.field1,
            'field2': self.field2,
        }
        // 触发客户端动作传递数据
        return {
            'type': 'ir.actions.client',
            'tag': 'pass_return_data',
            'params': return_data,
        }

3. 前端处理客户端动作

在源模型的JS中注册客户端动作,接收并处理返回数据:

registry.category("ir.actions.client").add("pass_return_data", (env, action) => {
    const returnData = action.params;
    // 更新源视图数据
    const currentView = env.services.view.currentView;
    if (currentView.modelName === 'your.source.model') {
        currentView.model.root.data.field1_from_return = returnData.field1;
        currentView.model.root.save();
    }
    // 关闭当前表单视图
    env.services.action.doAction({type: 'ir.actions.act_window_close'});
});

注意事项

  • 使用bus.bus传递事件时,必须指定当前用户作为接收方,避免数据泄露。
  • 弹窗模式下target='new'会自动关闭弹窗,无需额外处理关闭逻辑。
  • 复杂场景可通过上下文context传递临时数据,或使用模型临时字段存储中间值。

内容的提问来源于stack exchange,提问作者GNETO DOMINIQUE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 02:24:54