odoo前端js对象的扩展方法
odoo前端js对象的扩展方法
在 Odoo 中,你可以使用两种方法来扩展 JavaScript 对象:extends 和 patch。这两种方法在功能上有一些区别。
-
extends方法:- 使用
extends方法可以创建一个新的 JavaScript 对象,并继承自现有的对象。这意味着你可以在新对象中添加、修改或覆盖现有对象的属性和方法。 extends方法适用于对现有对象进行全面的扩展和修改,以满足特定的需求。你可以通过创建一个新的对象,并在其中添加自定义的属性和方法来实现扩展。- 使用
extends方法时,你需要确保新对象的原型链正确设置,以便正确继承和覆盖现有对象的属性和方法。
- 使用
-
patch方法:- 使用
patch方法可以直接修改现有的 JavaScript 对象,而无需创建新的对象。你可以通过patch方法来修改对象的属性和方法,添加新的属性和方法,或者删除现有的属性和方法。 patch方法适用于对现有对象进行局部的修改和调整,以满足特定的需求。你可以直接在现有对象上进行修改,而无需创建新的对象。- 使用
patch方法时,你需要确保正确地定位到要修改的对象,并进行相应的修改操作。
- 使用
总的来说,extends 方法适用于全面的扩展和修改,而 patch 方法适用于局部的修改和调整。选择使用哪种方法取决于你的具体需求和场景。
1、patch的实现
patch 一个简单的例子
/** @odoo-module **/import { _t } from "@web/core/l10n/translation";
import { patch } from "@web/core/utils/patch";
import { SearchBar } from "@web/search/search_bar/search_bar";patch(SearchBar.prototype, {getPreposition(searchItem) {let preposition = super.getPreposition(searchItem);if (this.fields[searchItem.fieldName].name == 'payment_date') {preposition = _t("until");}return preposition}
});
2、patch.js
先学习一下object对象,再来学习patch.js
patch对象的原型,调用了很多Object的静态方法,原则上就是在原型对象上动态增加或者替换新的属性。
// Replace the old property by the new one.Object.defineProperty(objToPatch, key, newProperty);
附录: patch.js 源文件
/** @odoo-module **//*** @typedef {{* originalProperties: Map<string, PropertyDescriptor>;* skeleton: object;* extensions: Set<object>;* }} PatchDescription*//** @type {WeakMap<object, PatchDescription>} */
const patchDescriptions = new WeakMap();/*** Create or get the patch description for the given `objToPatch`.* @param {object} objToPatch* @returns {PatchDescription}*/
function getPatchDescription(objToPatch) {if (!patchDescriptions.has(objToPatch)) {patchDescriptions.set(objToPatch, {originalProperties: new Map(),skeleton: Object.create(Object.getPrototypeOf(objToPatch)),extensions: new Set(),});}return patchDescriptions.get(objToPatch);
}/*** @param {object} objToPatch* @returns {boolean}*/
function isClassPrototype(objToPatch) {// class A {}// isClassPrototype(A) === false// isClassPrototype(A.prototype) === true// isClassPrototype(new A()) === false// isClassPrototype({}) === falsereturn Object.hasOwn(objToPatch, "constructor") && objToPatch.constructor?.prototype === objToPatch;
}/*** Traverse the prototype chain to find a potential property.* @param {object} objToPatch* @param {string} key* @returns {object}*/
function findAncestorPropertyDescriptor(objToPatch, key) {let descriptor = null;let prototype = objToPatch;do {descriptor = Object.getOwnPropertyDescriptor(prototype, key);prototype = Object.getPrototypeOf(prototype);} while (!descriptor && prototype);return descriptor;
}/*** Patch an object** If the intent is to patch a class, don't forget to patch the prototype, unless* you want to patch static properties/methods.** @template T* @template {T} U* @param {T} objToPatch The object to patch* @param {U} extension The object containing the patched properties* @returns {() => void} Returns an unpatch function*/
export function patch(objToPatch, extension) {if (typeof extension === "string") {throw new Error(`Patch "${extension}": Second argument is not the patch name anymore, it should be the object containing the patched properties`);}const description = getPatchDescription(objToPatch);description.extensions.add(extension);const properties = Object.getOwnPropertyDescriptors(extension);for (const [key, newProperty] of Object.entries(properties)) {const oldProperty = Object.getOwnPropertyDescriptor(objToPatch, key);if (oldProperty) {// Store the old property on the skeleton.Object.defineProperty(description.skeleton, key, oldProperty);}if (!description.originalProperties.has(key)) {// Keep a trace of original property (prop before first patch), useful for unpatching.description.originalProperties.set(key, oldProperty);}if (isClassPrototype(objToPatch)) {// A property is enumerable on POJO ({ prop: 1 }) but not on classes (class A {}).// Here, we only check if we patch a class prototype.newProperty.enumerable = false;}if ((newProperty.get && 1) ^ (newProperty.set && 1)) {// get and set are defined together. If they are both defined// in the previous descriptor but only one in the new descriptor// then the other will be undefined so we need to apply the// previous descriptor in the new one.const ancestorProperty = findAncestorPropertyDescriptor(objToPatch, key);newProperty.get = newProperty.get ?? ancestorProperty?.get;newProperty.set = newProperty.set ?? ancestorProperty?.set;}// Replace the old property by the new one.Object.defineProperty(objToPatch, key, newProperty);}// Sets the current skeleton as the extension's prototype to make// `super` keyword working and then set extension as the new skeleton.description.skeleton = Object.setPrototypeOf(extension, description.skeleton);return () => {// Remove the description to start with a fresh base.patchDescriptions.delete(objToPatch);for (const [key, property] of description.originalProperties) {if (property) {// Restore the original property on the `objToPatch` object.Object.defineProperty(objToPatch, key, property);} else {// Or remove the property if it did not exist at first.delete objToPatch[key];}}// Re-apply the patches without the current one.description.extensions.delete(extension);for (const extension of description.extensions) {patch(objToPatch, extension);}};
}相关文章:
odoo前端js对象的扩展方法
odoo前端js对象的扩展方法 在 Odoo 中,你可以使用两种方法来扩展 JavaScript 对象:extends 和 patch。这两种方法在功能上有一些区别。 extends 方法: 使用 extends 方法可以创建一个新的 JavaScript 对象,并继承自现有的对象。这…...
力扣双周赛 -- 117(容斥原理专场)
class Solution { public:long long c2(long long n){return n > 1? n * (n - 1) / 2 : 0;}long long distributeCandies(int n, int limit) {return c2(n 2) - 3 * c2(n - limit 1) 3 * c2(n - 2 * limit) - c2(n - 3 * limit - 1);} };...
基于Rabbitmq和Redis的延迟消息实现
1 基于Rabbitmq延迟消息实现 支付时间设置为30,未支付的消息会积压在mq中,给mq带来巨大压力。我们可以利用Rabbitmq的延迟队列插件实现消息前一分钟尽快处理 1.1定义延迟消息实体 由于我们要多次发送延迟消息,因此需要先定义一个记录消息…...
Masked Relation Learning for DeepFake Detection
一、研究背景 1.现有deepfake检测方法大多关注于局部伪影或面部不协调,较少挖掘局部区域间的关系。 2.现有关系挖掘类的工作往往忽略了关系信息的传播。 3.遮挡建模在减轻信息冗余的同时促进高级语义信息(诱导性偏差较小)的挖掘,有…...
R语言爬虫程序自动爬取图片并下载
R语言本身并不适合用来爬取数据,它更适合进行统计分析和数据可视化。而Python的requests,BeautifulSoup,Scrapy等库则更适合用来爬取网页数据。如果你想要在R中获取网页内容,你可以使用rvest包。 以下是一个简单的使用rvest包爬取…...
2023年10月国产数据库大事记-墨天轮
本文为墨天轮社区整理的2023年10月国产数据库大事件和重要产品发布消息。 目录 10月国产数据库大事记 TOP1010月国产数据库大事记(时间线)产品/版本发布兼容认证代表厂商大事记厂商活动排行榜新增数据库相关资料 10月国产数据库大事记 TOP10 10月国产…...
Linux内核分析(十四)--内存管理之malloc、free 实现原理
目录 一、引言 二、malloc实现方式 ------>2.1、动态内存分配的系统调用:brk / sbrk ------>2.2、malloc实现思路 ------------>2.2.1、最佳适应法 ------------>2.2.2、最差适应法 ------------>2.2.3、首次适应法 ------------>2.2.4、下一个适应…...
Hive函数
1. Hive 内置运算符 整体上,Hive 支持的运算符可以分为三大类:关系运算、算术运算、逻辑运算。 官方参考文档:LanguageManual UDF - Apache Hive - Apache Software Foundation 也可以使用下述方式查看运算符的使用方式: -- 显…...
教资笔记(目录)
目录 中小学教资笔记总结中学教资小学教资小学中学科一《综合素质》(通用):考情分析:学习笔记 小学科二《教育知识与能力》:考情分析:学习笔记: 中小学教资笔记总结 2023.9.16教资考试 笔试成绩…...
np.repeat()的注意事项
对于一个shape为(3, 2)的矩阵a, b a.repeat(9, axis1)。 那b[:, :9]是相同的,b[:, 9:]是相同的,意见 a np.random.rand(3, 2) b a.repeat(9, axis1) np.all(b[:, 0] b[:, 1]), np.all(b[:, 0] b[:, 9]) Out: (Tr…...
239. 滑动窗口最大值
239. 滑动窗口最大值 原题链接:完成情况:解题思路:参考代码:错误经验吸取 原题链接: 239. 滑动窗口最大值 https://leetcode.cn/problems/sliding-window-maximum/description/ 完成情况: 解题思路&…...
c++ barrier 使用详解
c barrier 使用详解 std::barrier c20 头文件 #include <barrier>。作用:一般被用来协调多个线程,在所有线程都到达屏障点之后,才允许它们继续执行,对于需要线程间同步的并行算法和任务来说非常有用。使用步骤:…...
c# 接口
c#接口 namespace demo1 {/// <summary>/// 接口使用interface关键字进行定义/// 接口中只能声明方法不能定义,也就是说声明的方法不能有方法体。/// 接口不能包含常量、字段、运算符、实例构造函数、析构函数或类型,不能包含静态成员。由于不能有…...
1、NPC 三电平SVPWM simulink仿真
1、SVPWM时间计算函数,是从matlab的SVPWM3L_TimingCalculation.p文件中反汇编出来的函数: function [TgABC_On ,TgABC_Off ,Sn ]SVPWM3L_TimingCalculation_frompfile (Vref ,DeltaVdc ,Fsw ) %#codegen %coder .allowpcode (plain ); TgABC_On [0 ,0 ,…...
JAVA对象列表强转失败,更好的方法
JAVA将无法强转的list泛型对象使用JSON工具类转换为list类 List<DiskUseRateVo> list JSON.parseArray(JSON.toJSONString(httpGet(url).getContent()), DiskUseRateVo.class);之前一直强转发现后续list.get(0)报错,用JSON解决了问题。...
2023最新版本 从零基础入门C++与QT(学习笔记) -5- 动态内存分配(new)
🎏C的动态内存要比C方便 🎄注意C申请内存的时候可以直接的初始化!!! 🎄格式(申请一块内存) 🎈new(关键字) 变量类型 🎄格式(申请多块内存&am…...
asp.net校园招聘管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio
一、源码特点 asp.net 校园招聘管理系统是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言开发 应用技术:asp.net c#s…...
flink的键值分区状态自动过期ttl配置
背景 flink的状态清理之前一直都是通过处理函数的ontimer设置定时器的方式清理掉那些无用的状态,但是这种方式容易出错而且代码也不优雅,使用flink提供的状态ttl的方式可以解决这个问题 flink键值分区状态ttl设置 文件系统/基于内存的状态后端的ttl设…...
解决Mac配置maven环境后,关闭终端后环境失效的问题(适用于所有终端关闭后环境失效的问题)
目录 问题的原因 解决方式一、每次打开终端时输入:"source ~/.bash_profile",这个方式比较繁琐 解决方式二、我们终端输入"vim ~/.zshrc"打开".zshrc"文件 1、我们输入以下代码: 2、首先需要按 " i…...
springboot运行jar包,实现复制jar包resources下文件、文件夹(可支持包含子文件夹)到指定的目录
背景: 以jar包运行时,获取文件目录时,会报错; idea运行不会报错。 代码: //复制文件夹到指定路径下 String srcFilePath Thread.currentThread().getContextClassLoader().getResource("").getPath() &…...
STM32单片机学习(28) —— STM32的SPI外设
文章目录概述SPI通信的移位机制(以bit为单位)SPI外设框图第一部分:数据通路SPI通信的数据帧格式SPI外设移位机制(以字节为单位)第二部分:主机时钟生成器SPI通信时钟频率与传输速率第三部分:主从…...
MBTI性格测试
简介 MBTI(Myers‑Briggs Type Indicator,迈尔斯‑布里格斯类型指标)是基于荣格心理类型理论发展出的性格类型工具,由凯瑟琳库克布里格斯及其女儿伊莎贝尔布里格斯迈尔斯创建。它通过四对偏好维度将个体的认知与行为倾向归纳为 16…...
终极鼠标连点器使用指南:3分钟掌握高效自动化技巧
终极鼠标连点器使用指南:3分钟掌握高效自动化技巧 【免费下载链接】MouseClick 🖱️ MouseClick 🖱️ 是一款功能强大的鼠标连点器和管理工具,采用 QT Widget 开发 ,具备跨平台兼容性 。软件界面美观 ,操作…...
2026论文降AI怎么挑?亲测好用工具附免费降AI指南
“您的论文AIGC率为42%,超出学校30%的合格线,请修改后重新提交。”赶毕业论文的同学这段时间估计没少收到这样的提醒。2026年知网、万方、维普等主流平台的AI检测算法持续迭代,把AI生成内容改到符合学校要求,已经成了毕业生的刚需…...
基于Arduino的智能蓝调节拍器:DIY音乐练习伴侣
1. 项目概述:一个能“演奏”蓝调的低成本节拍器玩乐器的人,对节拍器这东西又爱又恨。它像一位严厉的监工,用单调的“嘀嗒”声强迫你跟上节奏。但你想过没有,这个监工其实可以很有趣?几年前,我在练习蓝调吉他…...
告别混乱绑定!在UE5 GAS中优雅管理技能输入(基于GameplayTag)
告别混乱绑定!在UE5 GAS中优雅管理技能输入(基于GameplayTag)当你的UE5 RPG项目发展到中期,技能数量从十几个膨胀到几十个时,最痛苦的莫过于发现InputAction绑定已经变成一团乱麻。每次新增技能都要修改输入绑定逻辑&a…...
LangGraph状态机工程:构建复杂AI工作流的完整指南
传统RAG(检索增强生成)在处理简单的"单跳"问题时表现良好——“文章里提到了什么” “这个概念是什么意思”——但当问题涉及多个实体之间的关系、需要跨多个文档推理时,传统RAG就显得力不从心。GraphRAG(Graph-based R…...
深度解析网络设备权限管理工具:中兴光猫工厂模式与Telnet服务完整指南
深度解析网络设备权限管理工具:中兴光猫工厂模式与Telnet服务完整指南 【免费下载链接】zteOnu A tool that can open ZTE onu device factory mode 项目地址: https://gitcode.com/gh_mirrors/zt/zteOnu 在当今网络设备管理领域,获取设备完整控制…...
CSharpVerbalExpressions常见问题解答:解决开发者遇到的10个典型挑战
CSharpVerbalExpressions常见问题解答:解决开发者遇到的10个典型挑战 【免费下载链接】CSharpVerbalExpressions 项目地址: https://gitcode.com/gh_mirrors/cs/CSharpVerbalExpressions CSharpVerbalExpressions是一个强大的C#库,它通过类自然语…...
告别Selenium?手把手教你用Playwright录制脚本,5分钟搞定Web自动化测试
5分钟极速上手Playwright脚本录制:零代码实现Web自动化测试当产品经理突然丢给你一个刚上线的电商活动页,要求半小时内完成所有核心链路测试时,传统的手写Selenium脚本显然来不及。作为测试工程师,我最近发现微软开源的Playwright…...
