Налаштування типу представлення¶
Створити підклас існуючого представлення¶
Припустимо, нам потрібно створити власну версію загального представлення. Наприклад, представлення канбан з додатковим стрічкоподібним віджетом зверху (для відображення певної користувацької інформації). У такому випадку це можна зробити за кілька кроків:
Розширте controller/renderer/model канбану та зареєструйте його в реєстрі переглядів.
custom_kanban_controller.js
¶/** @odoo-module */ import { KanbanController } from "@web/views/kanban/kanban_controller"; import { kanbanView } from "@web/views/kanban/kanban_view"; import { registry } from "@web/core/registry"; // the controller usually contains the Layout and the renderer. class CustomKanbanController extends KanbanController { // Your logic here, override or insert new methods... // if you override setup(), don't forget to call super.setup() } CustomKanbanController.template = "my_module.CustomKanbanView"; export const customKanbanView = { ...kanbanView, // contains the default Renderer/Controller/Model Controller: CustomKanbanController, }; // Register it to the views registry registry.category("views").add("custom_kanban", customKanbanView);
У нашому користувацькому канбані ми визначили новий шаблон. Ми можемо або успадкувати шаблон контролера канбану та додати наші частини шаблону, або ж визначити абсолютно новий шаблон.
custom_kanban_controller.xml
¶<?xml version="1.0" encoding="UTF-8" ?> <templates> <t t-name="my_module.CustomKanbanView" t-inherit="web.KanbanView"> <xpath expr="//Layout" position="before"> <div> Hello world ! </div> </xpath> </t> </templates>
Використовуйте представлення з атрибутом
js_class
в arch.<kanban js_class="custom_kanban"> <templates> <t t-name="kanban-box"> <!--Your comment--> </t> </templates> </kanban>
Можливості розширення представлень безмежні. Хоча ми тут розширили лише контролер, ви також можете розширити рендерер, щоб додавати нові кнопки, змінювати спосіб представлення записів або налаштовувати випадаючий список, а також розширювати інші компоненти, такі як модель та buttonTemplate
.
Створення нового представлення з нуля¶
Створення нового подання – це складна тема. У цьому посібнику висвітлено лише основні кроки.
Створіть controller.
Основна роль контролера полягає в сприянні координації між різними компонентами представлення, такими як Renderer, Model та Layout.
beautiful_controller.js
¶/** @odoo-module */ import { Layout } from "@web/search/layout"; import { useService } from "@web/core/utils/hooks"; import { Component, onWillStart, useState} from "@odoo/owl"; export class BeautifulController extends Component { setup() { this.orm = useService("orm"); // The controller create the model and make it reactive so whenever this.model is // accessed and edited then it'll cause a rerendering this.model = useState( new this.props.Model( this.orm, this.props.resModel, this.props.fields, this.props.archInfo, this.props.domain ) ); onWillStart(async () => { await this.model.load(); }); } } BeautifulController.template = "my_module.View"; BeautifulController.components = { Layout };
Шаблон контролера відображає панель керування з Layout, а також renderer.
beautiful_controller.xml
¶<?xml version="1.0" encoding="UTF-8"?> <templates xml:space="preserve"> <t t-name="my_module.View"> <Layout display="props.display" className="'h-100 overflow-auto'"> <t t-component="props.Renderer" records="model.records" propsYouWant="'Hello world'"/> </Layout> </t> </templates>
Створіть renderer.
Основна функція renderer полягає у створенні візуального представлення даних шляхом рендерингу представлення, яке містить записи.
beautiful_renderer.js
¶import { Component } from "@odoo/owl"; export class BeautifulRenderer extends Component {} BeautifulRenderer.template = "my_module.Renderer";
beautiful_renderer.xml
¶<?xml version="1.0" encoding="UTF-8"?> <templates xml:space="preserve"> <t t-name="my_module.Renderer"> <t t-esc="props.propsYouWant"/> <t t-foreach="props.records" t-as="record" t-key="record.id"> // Show records </t> </t> </templates>
Створіть модель.
Роль моделі полягає в отриманні та управлінні всіма необхідними даними у поданні.
beautiful_model.js
¶/** @odoo-module */ import { KeepLast } from "@web/core/utils/concurrency"; export class BeautifulModel { constructor(orm, resModel, fields, archInfo, domain) { this.orm = orm; this.resModel = resModel; // We can access arch information parsed by the beautiful arch parser const { fieldFromTheArch } = archInfo; this.fieldFromTheArch = fieldFromTheArch; this.fields = fields; this.domain = domain; this.keepLast = new KeepLast(); } async load() { // The keeplast protect against concurrency call const { length, records } = await this.keepLast.add( this.orm.webSearchRead(this.resModel, this.domain, [this.fieldsFromTheArch], {}) ); this.records = records; this.recordsLength = length; } }
Примітка
Для складних випадків, замість створення моделі з нуля, також можна використовувати
RelationalModel
, яка використовується іншими представленнями.Створіть arch парсер.
Роль arch парсера полягає в розборі arch представлення, щоб воно мало доступ до інформації.
beautiful_arch_parser.js
¶/** @odoo-module */ import { XMLParser } from "@web/core/utils/xml"; export class BeautifulArchParser extends XMLParser { parse(arch) { const xmlDoc = this.parseXML(arch); const fieldFromTheArch = xmlDoc.getAttribute("fieldFromTheArch"); return { fieldFromTheArch, }; } }
Створіть представлення та об’єднайте всі частини разом, а потім зареєструйте вигляд у реєстрі представлень.
beautiful_view.js
¶/** @odoo-module */ import { registry } from "@web/core/registry"; import { BeautifulController } from "./beautiful_controller"; import { BeautifulArchParser } from "./beautiful_arch_parser"; import { BeautifylModel } from "./beautiful_model"; import { BeautifulRenderer } from "./beautiful_renderer"; export const beautifulView = { type: "beautiful", display_name: "Beautiful", icon: "fa fa-picture-o", // the icon that will be displayed in the Layout panel multiRecord: true, Controller: BeautifulController, ArchParser: BeautifulArchParser, Model: BeautifulModel, Renderer: BeautifulRenderer, props(genericProps, view) { const { ArchParser } = view; const { arch } = genericProps; const archInfo = new ArchParser().parse(arch); return { ...genericProps, Model: view.Model, Renderer: view.Renderer, archInfo, }; }, }; registry.category("views").add("beautifulView", beautifulView);
Оголосіть представлення у файлі arch.
... <record id="my_beautiful_view" model="ir.ui.view"> <field name="name">my_view</field> <field name="model">my_model</field> <field name="arch" type="xml"> <beautiful fieldFromTheArch="res.partner"/> </field> </record> ...