odoo17核心概念view2——view_service

2023-12-27 03:01

本文主要是介绍odoo17核心概念view2——view_service,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这是view系列的第二篇文章,介绍view_service.js
static\src\views\view_service.js

一、前端js

/** @odoo-module **/import { registry } from "@web/core/registry";
import { UPDATE_METHODS } from "@web/core/orm_service";export const viewService = {dependencies: ["orm"],start(env, { orm }) {let cache = {};function clearCache() {cache = {};const processedArchs = registry.category("__processed_archs__");processedArchs.content = {};processedArchs.trigger("UPDATE");}env.bus.addEventListener("CLEAR-CACHES", clearCache);env.bus.addEventListener("RPC:RESPONSE", (ev) => {const { model, method } = ev.detail.data.params;if (["ir.ui.view", "ir.filters"].includes(model)) {if (UPDATE_METHODS.includes(method)) {clearCache();}}});/*** Loads various information concerning views: fields_view for each view,* fields of the corresponding model, and optionally the filters.** @param {LoadViewsParams} params* @param {LoadViewsOptions} [options={}]* @returns {Promise<ViewDescriptions>}*/async function loadViews(params, options = {}) {const { context, resModel, views } = params;const loadViewsOptions = {action_id: options.actionId || false,load_filters: options.loadIrFilters || false,toolbar: (!context?.disable_toolbar && options.loadActionMenus) || false,};for (const key in options) {if (!["actionId", "loadIrFilters", "loadActionMenus"].includes(key)) {loadViewsOptions[key] = options[key];}}if (env.isSmall) {loadViewsOptions.mobile = true;}const filteredContext = Object.fromEntries(Object.entries(context || {}).filter(([k, v]) => k == "lang" || k.endsWith("_view_ref")));const key = JSON.stringify([resModel, views, filteredContext, loadViewsOptions]);if (!cache[key]) {debuggercache[key] = orm.call(resModel, "get_views", [], {context: filteredContext,views,options: loadViewsOptions,}).then((result) => {const { models, views } = result;const viewDescriptions = {fields: models[resModel],relatedModels: models,views: {},};for (const viewType in views) {const { arch, toolbar, id, filters, custom_view_id } = views[viewType];const viewDescription = { arch, id, custom_view_id };if (toolbar) {viewDescription.actionMenus = toolbar;}if (filters) {viewDescription.irFilters = filters;}viewDescriptions.views[viewType] = viewDescription;}return viewDescriptions;}).catch((error) => {delete cache[key];return Promise.reject(error);});}return cache[key];}return { loadViews };},
};registry.category("services").add("view", viewService);

1 、服务开头提供了一个清理缓存的函数clearCache, 将注册表中的registry.category(“processed_archs”)清空,并且触发它的update事件。
2、后面就是最重要的loadViews函数了,加载有关视图的各种信息:每个视图的字段视图,对应模型的字段,以及可选的过滤器。
输入参数params: 包含了上下文信息,模型,视图 ,举个例子:

context:{params:{action:201,cids:1,menu_id:124,model:'crax_demo.crax.demo',view_type:'list'}}
resModel:crax_demo.crax.demo
views:[[false,'list'],[false,'form'],[false,'search']]

输入参数option:是一个字典

actionid
loadActionMenus:true
LoadIrFilters:true

这一段代码是对传入的参数进行结构赋值,并且组装传入的option到loadViewsOptions ,同时组装filteredContext

  const { context, resModel, views } = params;const loadViewsOptions = {action_id: options.actionId || false,load_filters: options.loadIrFilters || false,toolbar: (!context?.disable_toolbar && options.loadActionMenus) || false,};for (const key in options) {if (!["actionId", "loadIrFilters", "loadActionMenus"].includes(key)) {loadViewsOptions[key] = options[key];}}if (env.isSmall) {loadViewsOptions.mobile = true;}const filteredContext = Object.fromEntries(Object.entries(context || {}).filter(([k, v]) => k == "lang" || k.endsWith("_view_ref")));

然后将这些变量转换成字符串

const key = JSON.stringify([resModel, views, filteredContext, loadViewsOptions]);

判断缓存中是否有这个key,如果有,则从缓存中返回,否则调用orm从后端获取

cache[key] = orm.call(resModel, "get_views", [], {context: filteredContext,views,options: loadViewsOptions,}).then((result) => {const { models, views } = result;const viewDescriptions = {fields: models[resModel],relatedModels: models,views: {},};for (const viewType in views) {const { arch, toolbar, id, filters, custom_view_id } = views[viewType];const viewDescription = { arch, id, custom_view_id };if (toolbar) {viewDescription.actionMenus = toolbar;}if (filters) {viewDescription.irFilters = filters;}viewDescriptions.views[viewType] = viewDescription;}return viewDescriptions;}).catch((error) => {delete cache[key];return Promise.reject(error);});

orm是一个promise,返回值直接付给了缓存, 后面统一返回缓存中的值。
call, then ,catch 这是promise标准的写法。

.call(resModel, "get_views", [], {context: filteredContext,views,options: loadViewsOptions,})

任何一个模型都有一个get_views方法,这是继承自它的父类 base,具体的实现是在base模块的ir_ui_view中
odoo\addons\base\models\ir_ui_view.py

@api.modeldef get_views(self, views, options=None):""" Returns the fields_views of given views, along with the fields ofthe current model, and optionally its filters for the given action.The return of the method can only depend on the requested view types,access rights (views or other records), view access rules, options,context lang and TYPE_view_ref (other context values cannot be used).Python expressions contained in views or representing domains (onpython fields) will be evaluated by the client with all the contextvalues as well as the record values it has.:param views: list of [view_id, view_type]:param dict options: a dict optional boolean flags, set to enable:``toolbar``includes contextual actions when loading fields_views``load_filters``returns the model's filters``action_id``id of the action to get the filters, otherwise loads the globalfilters or the model:return: dictionary with fields_views, fields and optionally filters"""省略100行。。。。return result

views: views:[[false,‘list’],[false,‘form’],[false,‘search’]]
options: actionid 等

返回值:
views : 各种类型view的id 和arch 以及其他信息
models: 模型的字段信息

.then((result) => {const { models, views } = result;const viewDescriptions = {fields: models[resModel],relatedModels: models,views: {},};for (const viewType in views) {const { arch, toolbar, id, filters, custom_view_id } = views[viewType];const viewDescription = { arch, id, custom_view_id };if (toolbar) {viewDescription.actionMenus = toolbar;}if (filters) {viewDescription.irFilters = filters;}viewDescriptions.views[viewType] = viewDescription;}return viewDescriptions;

这一段是根据orm的返回值 组装viewDescriptions 字段,并返回,这个字段包含了:

                    fields: models[resModel],relatedModels: models,views: {},

这里有个关键点 relatedModels, 通过debug可以看到,这是一个模型的所有的字段信息。是视图的显示中,它起到了驱动的作用。 关于这一点,后面再细聊。
后面的for循环是为了填充views这个字段,对于每种类型的视图,都包含了arch,id,custom_view_id等字段。

总结一波:
view_service有两个功能:
1、 清理缓存
2、从缓存中获取视图信息,如果没有则调用orm服务调用model的get_views方法从后端读取, 然后将返回的信息封装成一个对象返回,这个对象包含了

模型的字段信息
模型信息(包括模型的所有字段以及字段的相关信息),relatedModels 在前端是一个非常重要的概念
视图信息(各种类型视图的id,xml结构等)

关于menuService的介绍就告一段落。

这篇关于odoo17核心概念view2——view_service的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/541695

相关文章

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

PostgreSQL核心功能特性与使用领域及场景分析

PostgreSQL有什么优点? 开源和免费 PostgreSQL是一个开源的数据库管理系统,可以免费使用和修改。这降低了企业的成本,并为开发者提供了一个活跃的社区和丰富的资源。 高度兼容 PostgreSQL支持多种操作系统(如Linux、Windows、macOS等)和编程语言(如C、C++、Java、Python、Ruby等),并提供了多种接口(如JDBC、ODBC、ADO.NET等

【MRI基础】TR 和 TE 时间概念

重复时间 (TR) 磁共振成像 (MRI) 中的 TR(重复时间,repetition time)是施加于同一切片的连续脉冲序列之间的时间间隔。具体而言,TR 是施加一个 RF(射频)脉冲与施加下一个 RF 脉冲之间的持续时间。TR 以毫秒 (ms) 为单位,主要控制后续脉冲之前的纵向弛豫程度(T1 弛豫),使其成为显著影响 MRI 中的图像对比度和信号特性的重要参数。 回声时间 (TE)

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理 秒杀系统是应对高并发、高压力下的典型业务场景,涉及到并发控制、库存管理、事务管理等多个关键技术点。本文将深入剖析秒杀商品业务中常见的几个核心问题,包括 AOP 事务管理、同步锁机制、乐观锁、CAS 操作,以及用户限购策略。通过这些技术的结合,确保秒杀系统在高并发场景下的稳定性和一致性。 1. AOP 代理对象与事务管理 在秒杀商品

MVC(Model-View-Controller)和MVVM(Model-View-ViewModel)

1、MVC MVC(Model-View-Controller) 是一种常用的架构模式,用于分离应用程序的逻辑、数据和展示。它通过三个核心组件(模型、视图和控制器)将应用程序的业务逻辑与用户界面隔离,促进代码的可维护性、可扩展性和模块化。在 MVC 模式中,各组件可以与多种设计模式结合使用,以增强灵活性和可维护性。以下是 MVC 各组件与常见设计模式的关系和作用: 1. Model(模型)

计算机网络基础概念 交换机、路由器、网关、TBOX

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、VLAN是什么?二 、交换机三、路由器四、网关五、TBOXTelematics BOX,简称车载T-BOX,车联网系统包含四部分,主机、车载T-BOX、手机APP及后台系统。主机主要用于车内的影音娱乐,以及车辆信息显示;车载T-BOX主要用于和后台系统/手机APP通信,实现手机APP的车辆信息显示与控

01 Docker概念和部署

目录 1.1 Docker 概述 1.1.1 Docker 的优势 1.1.2 镜像 1.1.3 容器 1.1.4 仓库 1.2 安装 Docker 1.2.1 配置和安装依赖环境 1.3镜像操作 1.3.1 搜索镜像 1.3.2 获取镜像 1.3.3 查看镜像 1.3.4 给镜像重命名 1.3.5 存储,载入镜像和删除镜像 1.4 Doecker容器操作 1.4

【机器学习-一-基础概念篇】

机器学习 定义分类算法 应用 定义 机器学习最早是被Arthur Samuel 提出的一个概念,指计算机无需明确编程即可学习的研究领域。1950年他发明的跳棋程序,这个人机对弈游戏让他的声名鹊起,机器学习这个概念才进入大众的是视线。 在这个跳棋程序里,他编程了一种算法,这个程序与Arthur下了数万次跳棋,计算机逐渐学会了下在哪里有更大的可能会赢得比赛,哪里会输,通过这种方法,最