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

相关文章

Java Jackson核心注解使用详解

《JavaJackson核心注解使用详解》:本文主要介绍JavaJackson核心注解的使用,​​Jackson核心注解​​用于控制Java对象与JSON之间的序列化、反序列化行为,简化字段映射... 目录前言一、@jsonProperty-指定JSON字段名二、@JsonIgnore-忽略字段三、@Jso

Python列表去重的4种核心方法与实战指南详解

《Python列表去重的4种核心方法与实战指南详解》在Python开发中,处理列表数据时经常需要去除重复元素,本文将详细介绍4种最实用的列表去重方法,有需要的小伙伴可以根据自己的需要进行选择... 目录方法1:集合(set)去重法(最快速)方法2:顺序遍历法(保持顺序)方法3:副本删除法(原地修改)方法4:

SpringQuartz定时任务核心组件JobDetail与Trigger配置

《SpringQuartz定时任务核心组件JobDetail与Trigger配置》Spring框架与Quartz调度器的集成提供了强大而灵活的定时任务解决方案,本文主要介绍了SpringQuartz定... 目录引言一、Spring Quartz基础架构1.1 核心组件概述1.2 Spring集成优势二、J

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

Linux find 命令完全指南及核心用法

《Linuxfind命令完全指南及核心用法》find是Linux系统最强大的文件搜索工具,支持嵌套遍历、条件筛选、执行动作,下面给大家介绍Linuxfind命令完全指南,感兴趣的朋友一起看看吧... 目录一、基础搜索模式1. 按文件名搜索(精确/模糊匹配)2. 排除指定目录/文件二、根据文件类型筛选三、时间

MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析

《MyBatis-Plus中Service接口的lambdaUpdate用法及实例分析》本文将详细讲解MyBatis-Plus中的lambdaUpdate用法,并提供丰富的案例来帮助读者更好地理解和应... 目录深入探索MyBATis-Plus中Service接口的lambdaUpdate用法及示例案例背景

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

使用TomCat,service输出台出现乱码的解决

《使用TomCat,service输出台出现乱码的解决》本文介绍了解决Tomcat服务输出台中文乱码问题的两种方法,第一种方法是修改`logging.properties`文件中的`prefix`和`... 目录使用TomCat,service输出台出现乱码问题1解决方案问题2解决方案总结使用TomCat,

解决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