odoo|odoo 前端 patch(补丁)用法

有时,我们需要自定义或修改前端的格式或内容。
Odoo 提供了实用功能patch。
描述:
代码见:@web/core/utils/patch:
用法:

patch(obj, patchName, patchValue, options) Arguments obj (Object) – object that should be patchedpatchName (string) – unique string describing the patchpatchValue (Object) – an object mapping each key to a patchValueoptions (Object) – option object (see below)The patch function modifies in place the obj object (or class) and applies all key/value described in the patchValue object. This operation is registered under the patchName name, so it can be unpatched later if necessary.Most patch operations provide access to the parent value by using the _super property (see below in the examples). To do that, the patch method wraps each pair key/value in a getter that dynamically binds _super.The only option is pure (boolean). If set to true, the patch operation does not bind the _super property.

举一个简单的例子:
import { patch } from "@web/core/utils/patch"; const object = { field: "a field", fn() { // do something }, }; patch(object, "patch name", { fn() { // do things }, });

在上述代码中,是用patch修改object中的fn方法。
在使用patch时,我们经常需要修改父对象,由于我们使用的是补丁对象(非es6模式),我们不能使用 super关键字。因此,Odoo 提供了一种特殊的方法来模拟这种行为,即this._super:
patch(object, "_super patch", { fn() { this._super(...arguments); // do other things }, });

异步方法下,patch的使用
patch(object, "async _super patch", { async myAsyncFn() { const _super = this._super.bind(this); await Promise.resolve(); await _super(...arguments); // await this._super(...arguments); // this._super is undefined. }, });

【odoo|odoo 前端 patch(补丁)用法】支持属性
patch(object, "getter/setter patch", { get number() { return this._super() / 2; }, set number(value) { this._super(value * 2); }, });

class MyClass { static myStaticFn() {...} myPrototypeFn() {...} }// this will patch static properties!!! patch(MyClass, "static patch", { myStaticFn() {...}, }); // this is probably the usual case: patching a class method patch(MyClass.prototype, "prototype patch", { myPrototypeFn() {...}, });

#patch javascript类
由于 javascript 类使用原型继承,当希望从类中patch标准方法时,我们实际上需要 patch prototype:
class MyClass { static myStaticFn() {...} myPrototypeFn() {...} }// this will patch static properties!!! patch(MyClass, "static patch", { myStaticFn() {...}, }); // this is probably the usual case: patching a class method patch(MyClass.prototype, "prototype patch", { myPrototypeFn() {...}, });

此外,Javascript 以一种特殊的方式处理构造函数,这使得它无法被patch。唯一的解决方法是调用原始构造函数中的方法并patch该方法:
class MyClass { constructor() { this.setup(); } setup() { this.number = 1; } }patch(MyClass.prototype, "constructor", { setup() { this._super(...arguments); this.doubleNumber = this.number * 2; }, });

注意:对constructor直接patch是不可能的!
#patch compontant(owl),由于owl的component也是javascript类,所以写法如下:
patch(MyComponent.prototype, "my patch", { setup() { useMyHook(); }, });

#移除一个patch
代码见: @web/core/utils/patch
unpatch(obj, patchName) Arguments obj (Object) – object that should be unpatchedpatchName (string) – string describing the patch that should be removed

一个简单例子:
patch(object, "patch name", { ... }); // test stuff here unpatch(object, "patch name");

    推荐阅读