Odoo 13中如何让自定义模块晚于OCA插件加载以覆写JS函数?
Odoo 13重写OCA插件JS函数不生效的解决办法
问题背景
我在Odoo 13环境中搭建了oca_addons目录和自定义模块目录,oca_addons下安装了mail_quoted_reply插件及其他OCA插件。现在想要修改mail_message_reply.js中的一个函数,但始终无法生效——无论怎么操作,OCA插件的JS文件总是在自定义模块之后加载,导致我继承重写的函数被覆盖,实际调用的还是原函数。
已尝试的方案
- 在模块manifest文件中添加
'mail_quoted_reply'到依赖项,强制其先于自定义模块加载 - 创建单独的assets模板并设置
priority="1",试图提升加载优先级
自定义JS代码
odoo.define("my_module.mail_message_reply_override", function (require) { "use strict"; const MailThread = require('mail.widget.Thread'); MailThread.include({ events: _.extend({}, MailThread.prototype.events, { "click .o_thread_mail_message_reply": "_onClickMailMessageReply", }), _onClickMailMessageReply: function (event) { console.log("This never prints") }, });
解决步骤
1. 确认依赖配置完整性
检查自定义模块的__manifest__.py,确保depends字段同时包含mail和mail_quoted_reply——MailThread来自mail模块,必须保证基础模块和目标OCA插件都先加载:
'depends': ['mail', 'mail_quoted_reply'],
2. 调整资产模板加载顺序
Odoo的资产加载顺序不仅看模块依赖,还和资产模板的分组、优先级有关。要确保你的JS在mail_quoted_reply的JS之后加载,可采用以下两种方式:
方式一:继承web基础资产并设置更高优先级
<odoo> <template id="assets_backend" name="my_module assets" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> <script type="text/javascript" src="/my_module/static/src/js/mail_message_reply_override.js" priority="50"/> </xpath> </template> </odoo>
注:Odoo默认资产的priority一般在10-30区间,设置50能确保你的JS在大多数插件之后加载。
方式二:直接继承mail_quoted_reply的资产模板
如果mail_quoted_reply有自己的资产模板(比如mail_quoted_reply.assets_backend),直接在它后面插入你的JS:
<odoo> <template id="assets_mail_quoted_reply" inherit_id="mail_quoted_reply.assets_backend"> <xpath expr="." position="after"> <script type="text/javascript" src="/my_module/static/src/js/mail_message_reply_override.js"/> </xpath> </template> </odoo>
这种方式能100%保证你的JS在目标插件之后加载。
3. 调整JS重写方式
如果mail_quoted_reply是直接替换了MailThread的方法或事件(而非用include扩展),你的include会被覆盖,换用override强制覆盖:
odoo.define("my_module.mail_message_reply_override", function (require) { "use strict"; const MailThread = require('mail.widget.Thread'); // 用override替代include,强制覆盖目标方法 MailThread.override({ _onClickMailMessageReply: function (event) { console.log("This should print now"); // 需要保留原插件逻辑的话,取消下面注释 // this._super(...arguments); }, });
如果坚持用include,可以在init方法里重新绑定事件:
odoo.define("my_module.mail_message_reply_override", function (require) { "use strict"; const MailThread = require('mail.widget.Thread'); MailThread.include({ init: function () { this._super.apply(this, arguments); // 直接重新绑定事件,覆盖原绑定 this.events["click .o_thread_mail_message_reply"] = "_onClickMailMessageReply"; }, _onClickMailMessageReply: function (event) { console.log("This should print now"); }, });
4. 清除缓存并重启服务
修改完配置和代码后,必须执行以下操作:
- 进入Odoo后台,依次点击「设置」→「技术」→「缓存管理」→「清除缓存」
- 重启Odoo服务
- 用浏览器无痕模式测试,避免旧JS文件被缓存
内容的提问来源于stack exchange,提问作者Neill
相关产品推荐
相关产品推荐

