odoo 前端 patch(补丁)用法

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

patch(obj, patchName, patchValue, options)
Arguments
obj (Object)object that should be patched

patchName (string) – unique string describing the patch

patchValue (Object) – an object mapping each key to a patchValue

options (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.
  },
});

支持属性

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 unpatched

patchName (string) – string describing the patch that should be removed

一个简单例子:

patch(object, "patch name", { ... });
// test stuff here
unpatch(object, "patch name");

你可能感兴趣的