Odoo13编辑表单时如何在JS函数中获取当前模型实时表单数据
核心问题
你现有代码的写法完全不符合Odoo13前端框架的规范,拿不到值是必然的:
- 模块顶层写
var self = this指向的是模块闭包的全局作用域,根本不是表单组件实例,当然访问不到model属性。 - 用jQuery直接选DOM拿值的逻辑在Odoo表单里根本行不通:Odoo是单页应用,
document.ready触发时表单组件还没完成渲染,而且字段的DOM结构、id是Odoo框架动态生成的,你硬写的#checkDate选择器根本选不到正确的元素,更拿不到用户编辑中的未保存值。 - 全局挂载的
setInterval不会跟随页面切换销毁,会造成内存泄漏。
正确实现
Odoo13的表单数据统一由表单控制器(FormController)托管,用户编辑的未保存值存在控制器实例持有的model缓存里,必须通过继承表单控制器的方式拿到实例,才能正确获取实时数据,不要尝试直接操作DOM拿业务数据。
完整可运行代码如下:
odoo.define('jy.abc2', function(require) { 'use strict'; // 引入Odoo内置依赖 var FormController = require('web.FormController'); var ajax = require('web.ajax'); // 扩展原生表单控制器,注入自定义逻辑 FormController.include({ start: function () { this._super.apply(this, arguments); // 定时器挂载到组件实例上,方便后续销毁 this._jyPollTimer = setInterval(this._jySendRealtimeData.bind(this), 5000); }, destroy: function () { // 离开表单页时清除定时器,避免内存泄漏 if (this._jyPollTimer) { clearInterval(this._jyPollTimer); } this._super.apply(this, arguments); }, _jySendRealtimeData: function () { // 按需限定逻辑只在指定模型的表单执行,避免所有表单都触发请求 // if (this.model !== 'your.hotel.model') return; // 1. 获取当前模型名 var currentModel = this.model; // 2. 获取当前表单所有字段的实时值(包含未保存的编辑内容) var realtimeFormData = this.model.get(this.handle).data; // 直接从缓存对象取字段值,不要用jQuery找DOM var checkDate = realtimeFormData.checkDate; var orderNo = realtimeFormData.orderNo; // 用Odoo内置ajax发请求,自动带会话和csrf校验,不用手动处理 ajax.jsonRpc('/jy/abc/testjson', 'call', { 'hotelSeq': 111, 'orderNo': orderNo, 'currentModel': currentModel, 'allFields': realtimeFormData }).then(function (response) { console.log('后端返回结果:', response); }).guardedCatch(function (error) { console.error('请求失败:', error); }); } }); });
补充说明
this.model.get(this.handle).data返回的对象字段key和后端模型定义的字段名完全一致,注意不要写错字段名,比如后端定义是check_date就不要写成checkDate。- 后端控制器必须加
@http.route('/jy/abc/testjson', type='json', auth='user')装饰器,和前端jsonRpc请求格式匹配,不然会报400错误。 - 如果要做值变更触发的逻辑,不要用定时器轮询,可以直接监听表单的
field_changed事件,性能更好。
内容的提问来源于stack exchange,提问作者xflyson
相关产品推荐
相关产品推荐

