当前位置: 首页 > news >正文

odoo16前端框架源码阅读——boot.js

odoo16前端框架源码阅读——boot.js

从名字就能看出来,这个文件是一个启动文件。 odoo前端将所有的js打包成了两个文件,一个是common.js,另一个是backend.js, 而common.js 是最先加载的

在common.js打包的js文件中最先加载的是下面的文件,看名字就就知道这是为了兼容性,应该不重要。

/* /web/static/src/legacy/js/promise_extension.js */

第二个文件就是boot.js, 这个文件非常重要,从名字就能看出来,是一个启动文件

/* /web/static/src/boot.js */

odoo自定义了一个小型的模块系统,用于管理各odoo模块中的前端代码,并自行解决各代码之间的依赖关系。相关代码在addons/web/static/src/js/boot.js中,所以这个资源文件是需要第一个加载的文件。

boot.js在启动时,会创建一个全局的变量’odoo’,该变量有几个预设的函数,用于管理每个javascript模块。每个js模块其实就是一段代码,具有名称或者可能的依赖关系。

 if (!globalThis.odoo) {globalThis.odoo = {};}var odoo = globalThis.odoo;

定义了一个全局变量odoo,这里提一下globalThis,这是为了兼容node环境和浏览器环境而创造出的js环境下的顶层对象,在浏览器环境下跟window对象是一样的。

然后定了odoo对象的一些属性和函数,最常见的就是odoo.define

 odoo.define = function () {var args = Array.prototype.slice.call(arguments);var name = typeof args[0] === "string" ? args.shift() : "__odoo_job" + jobUID++;var factory = args[args.length - 1];var deps;if (args[0] instanceof Array) {deps = args[0];} else {deps = [];factory.toString().replace(commentRegExp, "").replace(cjsRequireRegExp, function (match, dep) {deps.push(dep);});}if (!(deps instanceof Array)) {throw new Error("Dependencies should be defined by an array", deps);}if (typeof factory !== "function") {throw new Error("Factory should be defined by a function", factory);}if (typeof name !== "string") {throw new Error("Invalid name definition (should be a string", name);}if (name in factories) {throw new Error("Service " + name + " already defined");}factory.deps = deps;factories[name] = factory;let promiseResolve;const promise = new Promise((resolve) => {promiseResolve = resolve;});jobs.push({name: name,factory: factory,deps: deps,resolve: promiseResolve,promise: promise,});deps.forEach(function (dep) {jobDeps.push({ from: dep, to: name });});odoo.__DEBUG__.processJobs();};

这个函数是定义odoo前端模块的函数。它可以有两个或者三个参数

两个参数,在模块中定义依赖关系。

odoo.define('module.A', function (require) {"use strict";var A = ...;return A;});odoo.define('module.B', function (require) {"use strict";var A = require('module.A');var B = ...; // something that involves Areturn B;});

上面的odoo.define()用于标准的odoo定义前端js模块的函数,第一个参数表示这个模块的名称,如果后面没有其它地方继承此js模块,也可以不用取名。第二个参数是一个匿名函数,传入参数为require,这个函数就是实际的js业务代码。如果你想引用其它的js模块,可以通过require(‘module.A’)的语法引入。这里的require名称是固定的,不能改变。另外odoo.define()也提供了一种显式的依赖定义方法,如:

odoo.define('module.Something', ['module.A', 'module.B'], function (require) {"use strict";var A = require('module.A');var B = require('module.B');// some code});

从上面的实例中,我们可以看出odoo.define()函数有三个参数:

  • moduleName:javascript模块的名称。它应该是一个唯一的字符串。约定是odoo插件的名称,后跟一个特定的描述。例如"web.Widget"描述了在Web插件中定义的模块,该模块导出Widget类(因为首字母大写),如果名称不是唯一的,则将引发异常并将其显示在控制台中。如果你定义的时候,没有此参数,则系统会自动生成一个带时间戳的唯一名称;
  • dependencies:第二个参数是可选的。如果给出的话,它应该是一个字符串列表,每个字符串对应一个javascript模块名称。这描述了执行模块之前需要加载的依赖项。如果此处未明确给出依赖项,则模块系统将通过在函数上调用toString,然后使用正则表达式查找所有require语句,从函数中提取它们;
  • function:最后一个参数是定义模块的函数。它的返回值是模块的值,可以将其传递给需要它的其他模块。请注意,异步模块有一个小例外,下面会讲到。

在Odoo中,有可能模块在准备好之前需要执行一些工作。例如,它可以执行rpc加载一些数据。在这种情况下,模块简单地返回一个Promise。 这时,在注册模块之前模块系统将仅等待Promise完成。

参考 https://www.cnblogs.com/pythonClub/p/17305994.html

相关文章:

  • ChinaSoft 论坛巡礼|开源软件供应链论坛
  • 酷柚易汛ERP - 序列号状态表操作指南
  • Swift 常用类别整理
  • [P7885][Android13] 解决5G信号良好状态栏信号只有两格的问题
  • CI/CD简介
  • 关于lumen严格模式接口mysql5.6和mysql5.7报错问题
  • 13.利用辗转相除法求两个整数的最大公约数和最小公倍数。如96,36
  • 常见面试题-计算机网络相关
  • GNU gold链接器 - target.cc 实现特定目标架构的支持
  • Python---元组的相关操作方法
  • wireshark打开tcpdump抓的包 vwr: Invalid data length runs past the end of the record
  • 如何用自然语言 5 分钟构建个人知识库应用?我的 GPTs builder 尝试
  • MarkDown文件插入图片(绝对\相对路径\调整图像大小位置)
  • Hadoop原理,HDFS架构,MapReduce原理
  • LeetCode Hot之七:438. 找到字符串中所有字母异位词
  • 【笔记】你不知道的JS读书笔记——Promise
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • axios 和 cookie 的那些事
  • Java 23种设计模式 之单例模式 7种实现方式
  • JavaScript 一些 DOM 的知识点
  • Laravel Telescope:优雅的应用调试工具
  • Puppeteer:浏览器控制器
  • windows-nginx-https-本地配置
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 爬虫模拟登陆 SegmentFault
  • 如何编写一个可升级的智能合约
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • ionic入门之数据绑定显示-1
  • Java数据解析之JSON
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • %@ page import=%的用法
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (175)FPGA门控时钟技术
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (附源码)ssm高校实验室 毕业设计 800008
  • (剑指Offer)面试题34:丑数
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)大型网站的系统架构
  • (轉貼) 寄發紅帖基本原則(教育部禮儀司頒布) (雜項)
  • .NET CLR基本术语
  • .net core webapi 大文件上传到wwwroot文件夹
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .Net Web窗口页属性
  • .Net 高效开发之不可错过的实用工具
  • .net连接oracle数据库
  • .NET中的Event与Delegates,从Publisher到Subscriber的衔接!
  • .secret勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复
  • @selector(..)警告提示
  • [20171101]rman to destination.txt
  • [Android]RecyclerView添加HeaderView出现宽度问题
  • [Angular] 笔记 6:ngStyle
  • [AS3]URLLoader+URLRequest+JPGEncoder实现BitmapData图片数据保存
  • [C#]DataTable常用操作总结【转】
  • [C++]类和对象(中)