odoo17开发教程(18):patch的用法简介

有时,我们需要自定义用户界面的工作方式。一些受支持的应用程序接口可以满足许多常见需求。例如,所有注册表都是很好的扩展点:字段注册表允许添加/删除专门的字段组件,或者主组件注册表允许添加应始终显示的组件。

然而,在某些情况下,这些注册表并不足够。在这种情况下,我们可能需要在原处修改一个对象或一个类。为此,Odoo 提供了实用功能 patch。它主要用于覆盖/更新某些不受自己控制的其他组件/代码的行为。

说明

补丁功能位于 @web/core/utils/patch 中:

patch(objToPatchextension)

修补简单对象

下面是一个如何修补对象的简单示例:

import { patch } from "@web/core/utils/patch";

const object = {
  field: "a field",
  fn() {
    // do something
  },
};

patch(object, {
  fn() {
    // do things
  },
});

在修补函数时,我们通常希望能够访问父函数。为此,我们只需使用本地 super 关键字即可:

patch(object, {
  fn() {
    super.fn(...arguments);
    // do other things
  },
});

super 只能在方法中使用,不能在函数中使用。这意味着以下结构对 javascript 无效。

const obj = {
  a: function () {
    // Throws: "Uncaught SyntaxError: 'super' keyword unexpected here"
    super.a();
  },
  b: () => {
    // Throws: "Uncaught SyntaxError: 'super' keyword unexpected here"
    super.b();
  },
};

还支持getter和setter:

patch(object, {
  get number() {
    return super.number / 2;
  },
  set number(value) {
    super.number = value;
  },
});

修补 JavaScript 类

补丁功能可用于任何对象或 ES6 类。

不过,由于 javascript 类采用原型继承方式,因此当我们希望对类中的标准方法打补丁时,实际上需要对原型打补丁:

class MyClass {
  static myStaticFn() {...}
  myPrototypeFn() {...}
}

// this will patch static properties!!!
patch(MyClass, {
  myStaticFn() {...},
});

// this is probably the usual case: patching a class method
patch(MyClass.prototype, {
  myPrototypeFn() {...},
});

此外,Javascript 会以一种特殊的本地方式处理构造函数,因此无法对其进行修补。唯一的解决办法是调用原始构造函数中的一个方法,然后对该方法进行修补:

class MyClass {
  constructor() {
    this.setup();
  }
  setup() {
    this.number = 1;
  }
}

patch(MyClass.prototype, {
  setup() {
    super.setup(...arguments);
    this.doubleNumber = this.number * 2;
  },
});

修补组件

组件是由 javascript 类定义的,因此上述所有信息仍然有效。因此,Owl 组件应使用设置方法,这样它们也可以很容易地打补丁:

patch(MyComponent.prototype, {
  setup() {
    useMyHook();
  },
});

删除补丁
patch 函数会返回对应的补丁。这主要用于测试目的,即在测试开始时打上补丁,并在测试结束时取消补丁。

const unpatch = patch(object, { ... });
// test stuff here
unpatch();

将同一修补程序应用于多个对象
 

const obj1 = {
  method() {
    doSomething();
  },
};

const obj2 = {
  method() {
    doThings();
  },
};

function createExtensionObj() {
  return {
    method() {
      super.method();
      doCommonThings();
    },
  };
}

patch(obj1, createExtensionObj());
patch(obj2, createExtensionObj());

上一篇 odoo17开发教程(17):美化UI界面_odoo17-CSDN博客

下一篇 odoo17开发教程(19):odoo js框架里的注册表-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值