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

相关文章

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.

提示:Decompiled.class file,bytecode version如何解决

《提示:Decompiled.classfile,bytecodeversion如何解决》在处理Decompiled.classfile和bytecodeversion问题时,通过修改Maven配... 目录问题原因总结问题1、提示:Decompiled .class file,China编程 bytecode

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

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

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

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件