Odoo 视图继承不是“把 XML 复制一份”:XPath、position 和 primary/extension 讲透
看懂 ir.ui.view 如何把继承链拼成最终 arch,为什么 XPath 找不到、position 失效,往往不是 Odoo 随机坏了。
TOPIC PICKS
看懂 ir.ui.view 如何把继承链拼成最终 arch,为什么 XPath 找不到、position 失效,往往不是 Odoo 随机坏了。
可以顺着继续读的相邻方向
很多系统对前端异常的态度还停留在“浏览器会报错、开发者自己看 console”。但 Odoo 的 `error_service.js` 和 `error_handlers.js` 说明,成熟 Web Client 会把异常统一包装、分流、降噪、弹窗化,再根据用户身份决定到底展示多少信息。它处理的不是“报不报错”,而是错误如何进入产品级运行时。
很多人一听到组件通信,就想上全局事件中心,结果事件来源越来越乱、页面切换后残留监听越来越多。Odoo 的 `useBus`、局部 `EventBus` 和组件销毁时自动解绑的设计说明,真正可靠的前端通信不是“谁都能发谁都能听”,而是事件范围、宿主对象与生命周期三件事必须同时说清。
很多 OWL 初学者把 env 当成“全局变量包”,结果组件一复杂,就会遇到状态串味、关闭行为互相污染、父子约定不清这些问题。Odoo 在 `useSubEnv` 与 `useChildSubEnv` 上的用法说明,env 真正扮演的是一层层收窄边界的运行时上下文,而不是所有人抢着写的公共抽屉。
很多人把 Odoo 的 many2one 字段理解成一个带搜索的下拉框:输入关键字、调 `name_search`、选中一项、结束。但从 `many2one_field.js`、`many2one.js`、`record_autocomplete.js` 看,官方实际维护的是一条关系选择链路:字段选项决定是否允许创建/编辑/快速创建,动态 domain 与上下文在每次搜索前现算,候选结果会进入 name service 缓存,超出上限后再切到 Search More 对话框。本文讲清 many2one 为什么远比“输入框 + 下拉”复杂。
很多人觉得富文本编辑器里“光标别乱跳”只是体验细节,但从 `selection_plugin.js` 与 `utils/selection.js` 看,Odoo HTML Editor 为此单独维护了一整层选区系统:记录 editable 内外选区、识别保护节点、归一化深层光标位置、在节点移动/删除/解包时同步修正 cursor,并在滚动容器里主动把选区滚进可视区。本文讲清编辑器为什么不能把浏览器原生 Selection 当成最终答案。
很多人学 Odoo OWL 页面时,会把数据层理解成“组件启动时调一次 RPC,把结果塞进 state,后面 props 变了再调一次”。但从 `model.js` 来看,官方把页面模型单独抽成 `Model` 类,用 `useModel()` / `useModelWithSampleData()` 管初始化、服务注入、首次加载、props 变化重载、竞态串行化,以及空数据时的 sample ORM 兜底。本文讲清 Odoo 为什么不鼓励把页面数据逻辑直接糊在组件里。