odoo17核心概念view6——用js_class扩展formview

2023-12-26 16:20

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

这是view系列的第六篇文章,我们学习用js_class来扩展view
学习odoo的一大窍门就是抄,因为odoo本身就是一个庞大的代码库,抄过来,改改就能用

1、找一个js_class的案例

搜索js_class,出现一堆结果,随便看一个

<form string="Account Entry" js_class="account_move_form">

搜索account_move_form 找到对应的js文件

/** @odoo-module **/import { registry } from "@web/core/registry";
import { createElement, append } from "@web/core/utils/xml";
import { Notebook } from "@web/core/notebook/notebook";
import { formView } from "@web/views/form/form_view";
import { FormCompiler } from "@web/views/form/form_compiler";
import { FormRenderer } from "@web/views/form/form_renderer";
import { FormController } from '@web/views/form/form_controller';
import { useService } from "@web/core/utils/hooks";export class AccountMoveController extends FormController {setup() {super.setup();this.account_move_service = useService("account_move");}async deleteRecord() {if ( !await this.account_move_service.addDeletionDialog(this, this.model.root.resId)) {return super.deleteRecord(...arguments);}}
};export class AccountMoveFormNotebook extends Notebook {async changeTabTo(page_id) {if (this.props.onBeforeTabSwitch) {await this.props.onBeforeTabSwitch(page_id);}this.state.currentPage = page_id;}
}
AccountMoveFormNotebook.template = "account.AccountMoveFormNotebook";
AccountMoveFormNotebook.props = {...Notebook.props,onBeforeTabSwitch: { type: Function, optional: true },
}
export class AccountMoveFormRenderer extends FormRenderer {async saveBeforeTabChange() {if (this.props.record.isInEdition && await this.props.record.isDirty()) {const contentEl = document.querySelector('.o_content');const scrollPos = contentEl.scrollTop;await this.props.record.save();if (scrollPos) {contentEl.scrollTop = scrollPos;}}}
}
AccountMoveFormRenderer.components = {...FormRenderer.components,AccountMoveFormNotebook: AccountMoveFormNotebook,
}
export class AccountMoveFormCompiler extends FormCompiler {compileNotebook(el, params) {const originalNoteBook = super.compileNotebook(...arguments);const noteBook = createElement("AccountMoveFormNotebook");for (const attr of originalNoteBook.attributes) {noteBook.setAttribute(attr.name, attr.value);}noteBook.setAttribute("onBeforeTabSwitch", "() => __comp__.saveBeforeTabChange()");const slots = originalNoteBook.childNodes;append(noteBook, [...slots]);return noteBook;}
}export const AccountMoveFormView = {...formView,Renderer: AccountMoveFormRenderer,Compiler: AccountMoveFormCompiler,Controller: AccountMoveController,
};registry.category("views").add("account_move_form", AccountMoveFormView);

通过上面的代码,我们看到它扩展了Renderer,Compiler,Controller三个组件,
而其他的属性通过…formView 解构赋值,值得注意的是这一句一定要放在最上面,因为后面的值会覆盖前面的,最后将这个新的结构体注册到注册表中。

2、看看formView原版

我们看看原来的formView是怎么写的,从代码看,formView是一个字典,包含了诸多属性

    type: "form",			                          视图类型		display_name: "Form",                       显示名称multiRecord: false,                            是否支持多行searchMenuTypes: [],                         搜索菜单类型,什么鬼?Controller: FormController,                 Controller组件(重要)Renderer: FormRenderer,					renderer组件(重要)ArchParser: FormArchParser,				arch解析器,(重要)Model: RelationalModel,						model (重要)Compiler: FormCompiler,					编译器(将xml文件编译成qweb模板,重要)buttonTemplate: "web.FormView.Buttons",    button模板

通常对视图的扩展就是修改它的Controller和Render组件。修改完之后生成一个新的字典,然后生成一个新的名字注册到注册表中。 然后在js_class中指定这个名称,前端解析xml的时候就会根据这个js_class名称去注册表中查找对应的信息,然后渲染页面。

/** @odoo-module **/import { registry } from "@web/core/registry";
import { RelationalModel } from "@web/model/relational_model/relational_model";
import { FormRenderer } from "./form_renderer";
import { FormArchParser } from "./form_arch_parser";
import { FormController } from "./form_controller";
import { FormCompiler } from "./form_compiler";export const formView = {type: "form",					display_name: "Form",multiRecord: false,searchMenuTypes: [],Controller: FormController,Renderer: FormRenderer,ArchParser: FormArchParser,Model: RelationalModel,Compiler: FormCompiler,buttonTemplate: "web.FormView.Buttons",props: (genericProps, view) => {const { ArchParser } = view;const { arch, relatedModels, resModel } = genericProps;const archInfo = new ArchParser().parse(arch, relatedModels, resModel);return {...genericProps,Model: view.Model,Renderer: view.Renderer,buttonTemplate: genericProps.buttonTemplate || view.buttonTemplate,Compiler: view.Compiler,archInfo,};},
};registry.category("views").add("form", formView);

3、做一个对form视图简单的扩展

js文件

/** @odoo-module **/import { registry } from "@web/core/registry";
import { formView } from "@web/views/form/form_view";
import { FormController } from '@web/views/form/form_controller';export class DemoFormController extends FormController {
};DemoFormController.template = "crax_demo.demo_form_controller"export const CraxDemoFormView = {...formView,Controller: DemoFormController,
};registry.category("views").add("crax_demo_form_view", CraxDemoFormView);

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<templates><t t-name="crax_demo.demo_form_controller" t-inherit="web.FormView" t-inherit-mode="primary"><xpath expr="//div[hasclass('o_form_view_container')]" position="inside"><div style="color:red;">hello world</div></xpath></t>
</templates>

这里只是简单的在o_form_view_container里面加了一个红色的hello,world!
例子很简单,但是套路讲明白了。

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



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

相关文章

Java Jackson核心注解使用详解

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

VSCode中配置node.js的实现示例

《VSCode中配置node.js的实现示例》本文主要介绍了VSCode中配置node.js的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一.node.js下载安装教程二.配置npm三.配置环境变量四.VSCode配置五.心得一.no

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

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

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

Node.js 数据库 CRUD 项目示例详解(完美解决方案)

《Node.js数据库CRUD项目示例详解(完美解决方案)》:本文主要介绍Node.js数据库CRUD项目示例详解(完美解决方案),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考... 目录项目结构1. 初始化项目2. 配置数据库连接 (config/db.js)3. 创建模型 (models/

使用Node.js制作图片上传服务的详细教程

《使用Node.js制作图片上传服务的详细教程》在现代Web应用开发中,图片上传是一项常见且重要的功能,借助Node.js强大的生态系统,我们可以轻松搭建高效的图片上传服务,本文将深入探讨如何使用No... 目录准备工作搭建 Express 服务器配置 multer 进行图片上传处理图片上传请求完整代码示例

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

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放