Odoo 12 与 Odoo 14 JavaScript 组件兼容性差异详解

1次阅读

Odoo 12 与 Odoo 14 JavaScript 组件兼容性差异详解

本文解析 Odoo 12 中无法运行 Odoo 14 标准 js 小部件代码的根本原因——web.public.widget 在 Odoo 12 中尚未引入,需降级适配为 website.snippet.editor 或 core.Widget 并调整生命周期方法。

本文解析 odoo 12 中无法运行 odoo 14 标准 js 小部件代码的根本原因——`web.public.widget` 在 odoo 12 中尚未引入,需降级适配为 `website.snippet.editor` 或 `core.widget` 并调整生命周期方法。

在 Odoo 14 中,前端 javaScript 扩展广泛采用 web.public.widget 作为公共网站组件的基类,它提供了标准化的 dom 选择器绑定、事件委托异步初始化(start())等能力。然而,该模块直到 Odoo 13.0 才正式引入,Odoo 12.0 的前端架构中并不存在 web.public.widget —— 这正是您提供的代码在 Odoo 12 环境下报错(如 Cannot read Property ‘extend’ of undefined)的直接原因。

要使相同功能在 Odoo 12 中正常工作,必须进行以下关键改造:

✅ 1. 替换基类:从 web.public.widget 降级为 core.Widget

Odoo 12 支持 web.core 模块中的通用 Widget 类,它是所有前端组件的原始基类,具备 start()、事件绑定(this.$el.on(…))等基础能力:

odoo.define('product_dimensions.website_sale', function (require) {     "use strict";      var core = require('web.core');     var _t = core._t;     var ajax = require('web.ajax');     var Widget = core.Widget; // ✅ Odoo 12 兼容基类      var ProductDimensions = Widget.extend({         // 注意:Odoo 12 不支持 selector + 自动绑定,需手动触发初始化         start: function () {             var self = this;             // 显式绑定到目标容器(如 .oe_website_sale)             this.$el = $(this.el).find('.oe_website_sale');             if (!this.$el.length) return;              this.product_id = this.$el.find('#product_id').val();              // ✅ 手动绑定事件(替代 events: {...} 声明式语法)             this.$el.on('change', 'input[name="wide"]', function () {                 self._onWidthChange();             });             this.$el.on('change', 'input[name="high"]', function () {                 self._onHeightChange();             });              return this._super.apply(this, arguments);         },          _onWidthChange: function () {             var wide = parseFloat($('input[name="wide"]').val());             console.log(this.product_id);             ajax.jsonRpc("/shop/product/min_dimensions", 'call', {'product_id': this.product_id}).then(function (data) {                 if (wide < data.wide_mini) {                     alert(_t('The number you entered is less than the minimum width:') + data.wide_mini);                 } else if (wide > data.wide_max) {                     alert(_t('The number you entered is greater than the maximum width:') + data.wide_max);                 }             });         },          _onHeightChange: function () {             var high = parseFloat($('input[name="high"]').val());             ajax.jsonRpc("/shop/product/min_dimensions", 'call', {'product_id': this.product_id}).then(function (data) {                 if (high < data.high_mini) {                     alert(_t('The number you entered is less than the minimum height:') + data.high_mini);                 } else if (high > data.high_max) {                     alert(_t('The number you entered is greater than the maximum height:') + data.high_max);                 }             });         },     });      // ✅ 注册为全局小部件(Odoo 12 推荐方式)     core.action_registry.add('product_dimensions_website_sale', ProductDimensions);      return ProductDimensions; });

⚠️ 2. 关键注意事项

  • 无自动 selector 匹配:Odoo 12 的 Widget 不支持 selector 属性自动查找并实例化 DOM 节点,必须在 start() 中显式定位(如 $(this.el).find(…))并手动绑定事件。
  • 生命周期差异:start() 是唯一可靠的初始化钩子;避免依赖 init() 或 willStart()(后者在 Odoo 12 中未定义)。
  • 模块依赖精简:移除 web.public.widget 依赖项,仅保留 web.core 和 web.ajax。
  • 模板加载时机:确保该 JS 在页面 DOM 加载完毕后执行(建议通过 <script type="text/<a style=" color: text-decoration:underline title="javascript" href="https://www.php.cn/zt/15724.html" target="_blank">javascript"> 嵌入或在 assets_frontend 中正确继承)。</script>

? 总结

跨版本 JS 兼容的核心原则是「向后兼容、渐进降级」:Odoo 14 的 publicWidget 是对 Widget 的封装增强,而 Odoo 12 需回归基础 Widget 实现。只要规避高阶 API(如声明式 events、selector 自动挂载),改用手动 DOM 操作与事件绑定,即可在 Odoo 12 中完整复现尺寸校验逻辑。建议在 __manifest__.py 中明确指定 version 和 depends,并在开发环境严格按目标版本测试前端行为。

立即学习Java免费学习笔记(深入)”;

text=ZqhQzanResources