Компоненти Owl¶
Фреймворк Odoo Javascript використовує спеціальний фреймворк компонентів під назвою Owl. Це декларативна система компонентів, частково натхненна Vue та React. Компоненти визначаються за допомогою QWeb шаблонів, доповнених деякими специфічними для Owl директивами. Офіційна документація Owl містить повний довідник та підручник.
Важливо
Хоча код можна знайти в модулі web, він зберігається з окремого репозиторію GitHub. Тому будь-які зміни до Owl слід вносити через запит на зміну на https://github.com/odoo/owl.
Примітка
Наразі всі версії Odoo (починаючи з версії 14) використовують одну й ту саму версію Owl.
Використання компонентів Owl¶
У Owl документація вже детально описано фреймворк Owl, тому на цій сторінці буде надано лише інформацію, специфічну для Odoo. Але спочатку давайте подивимося, як можна створити простий компонент в Odoo.
const { useState } = owl.hooks;
const { xml } = owl.tags;
class MyComponent extends Component {
setup() {
this.state = useState({ value: 1 });
}
increment() {
this.state.value++;
}
}
MyComponent.template = xml
`<div t-on-click="increment">
<t t-esc="state.value">
</div>`;
Цей приклад показує, що Owl доступний як бібліотека в глобальному просторі імен як owl: його можна просто використовувати, як і більшість бібліотек в Odoo. Зверніть увагу, що ми визначили тут шаблон як статичну властивість, але без використання ключового слова static, яке недоступне в деяких браузерах (код javascript Odoo повинен відповідати стандарту Ecmascript 2019).
Тут ми визначаємо шаблон у коді javascript за допомогою допоміжного засобу xml. Однак це корисно лише для початку роботи. На практиці шаблони в Odoo слід визначати в файлі xml, щоб їх можна було перекладати. У цьому випадку компонент повинен визначати лише назву шаблону.
На практиці більшість компонентів повинні визначати 2 або 3 файли, розташовані в одному місці: файл javascript (my_component.js), файл шаблону (my_component.xml) і, за бажанням, файл scss (або css) (my_component.scss). Ці файли потім слід додати до якогось пакету ресурсів. Веб-фреймворк подбає про завантаження файлів javascript/css та завантаження шаблонів в Owl.
Ось як слід визначити вищезгаданий компонент:
const { useState } = owl.hooks;
class MyComponent extends Component {
...
}
MyComponent.template = 'myaddon.MyComponent';
А шаблон тепер знаходиться у відповідному xml-файлі:
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="myaddon.MyComponent">
<div t-on-click="increment">
<t t-esc="state.value"/>
</div>
</t>
</templates>
Примітка
Назви шаблонів повинні відповідати домовленості addon_name.ComponentName.
Перегляньте також
Кращі практики¶
Перш за все, компоненти є класами, тому вони мають конструктор. Але конструктори є спеціальними методами в javascript, які не можна перезаписати жодним чином. Оскільки це іноді корисний шаблон в Odoo, ми повинні переконатися, що жоден компонент в Odoo безпосередньо не використовує метод конструктора. Натомість компоненти повинні використовувати метод setup:
// correct:
class MyComponent extends Component {
setup() {
// initialize component here
}
}
// incorrect. Do not do that!
class IncorrectComponent extends Component {
constructor(parent, props) {
// initialize component here
}
}
Ще однією гарною практикою є використання узгодженої домовленості для назв шаблонів: addon_name.ComponentName. Це запобігає конфлікту назв між додатками odoo.
Список посилань¶
Веб-клієнт Odoo побудований на компонентах Owl. Для спрощення роботи фреймворк Odoo javascript надає набір загальних компонентів, які можна повторно використовувати в деяких типових ситуаціях, таких як випадаючі меню, прапорці або календарі. На цій сторінці пояснюється, як використовувати ці загальні компоненти.
Технічна назва |
Короткий опис |
|---|---|
компонент свайпера для виконання дій під час сенсорного свайпу |
|
простий компонент-чекбокс з міткою поруч |
|
список кольорів на вибір |
|
повнофункціональний випадаючий список |
|
компонент для навігації між сторінками за допомогою вкладок |
|
невеликий компонент для обробки пагінації |
|
компонент, що випадає, для вибору між різними опціями |
|
список тегів, що відображаються у вигляді округлих таблеток |
ActionSwiper¶
Розташування¶
@web/core/action_swiper/action_swiper
Опис¶
Це компонент, який може виконувати дії, коли елемент свайпом проводиться горизонтально. Свайпер обтікає цільовий елемент, додаючи до нього дії. Дія виконується, як тільки користувач відпустить свайпер, пройшовши частину його ширини.
<ActionSwiper onLeftSwipe="Object" onRightSwipe="Object">
<SomeElement/>
</ActionSwiper>
Найпростіший спосіб використання компонента - це використання його навколо цільового елемента безпосередньо в шаблоні xml, як показано вище. Але іноді може знадобитися розширити існуючий елемент, не дублюючи шаблон. Це можна зробити.
Якщо ви хочете розширити поведінку існуючого елемента, ви повинні розмістити елемент всередині, обернувши його безпосередньо. Крім того, ви можете умовно додати властивості, щоб керувати тим, коли елемент може бути прокручуваним, його анімацією та мінімальною частиною, яку потрібно прокрутити, щоб виконати дію.
Ви можете використовувати компонент для легкої взаємодії із записами, повідомленнями, елементами у списках та багатьма іншими функціями.
У наступному прикладі створюється базовий компонент ActionSwiper. Тут свайп увімкнено в обох напрямках.
<ActionSwiper
onRightSwipe="
{
action: '() => Delete item',
icon: 'fa-delete',
bgColor: 'bg-danger',
}"
onLeftSwipe="
{
action: '() => Star item',
icon: 'fa-star',
bgColor: 'bg-warning',
}"
>
<div>
Swipable item
</div>
</ActionSwiper>
Примітка
Дії переставляють місцями під час використання мов із письмом справа наліво (RTL).
Props¶
Name |
Тип |
Опис |
|---|---|---|
|
|
необов’язкове логічне значення для визначення, чи присутній ефект переміщення під час проведення пальцем |
|
|
додаткова анімація, яка використовується після завершення свайпу ( |
|
|
якщо є, свайпер дій можна провести ліворуч |
|
|
якщо є, свайпер дій можна провести праворуч |
|
|
необов’язкове мінімальне співвідношення ширини, яке потрібно провести пальцем для виконання дії |
Ви можете використовувати обидва пропи onLeftSwipe та onRightSwipe одночасно.
Object, що використовується для прокрутки вліво/вправо, повинен містити:
action– це викликуванаFunction, яка служить зворотним викликом. Після завершення свайпу в заданому напрямку виконується ця дія.
icon– це клас іконок, який слід використовувати, зазвичай для представлення дії. Він має бутирядком.
bgColor– це колір фону, що використовується для декорування дії. Може бути одним із наступних значень контекстного кольору bootstrap (danger,info,secondary,successабоwarning).Ці значення необхідно задати для визначення поведінки та візуального аспекту свайпера.
Приклад: Розширення існуючих компонентів¶
У наступному прикладі ви можете використовувати xpath для обгортання існуючого елемента в компоненті ActionSwiper. Тут додано свайпер, щоб позначити повідомлення як прочитане в пошті.
<xpath expr="//*[hasclass('o_Message')]" position="after">
<ActionSwiper
onRightSwipe="messaging.device.isMobile and messageView.message.isNeedaction ?
{
action: () => messageView.message.markAsRead(),
icon: 'fa-check-circle',
bgColor: 'bg-success',
} : undefined"
/>
</xpath>
<xpath expr="//ActionSwiper" position="inside">
<xpath expr="//*[hasclass('o_Message')]" position="move"/>
</xpath>
CheckBox¶
Розташування¶
@web/core/checkbox/checkbox
Опис¶
Це простий компонент-прапорець із міткою поруч. Чекбокс пов’язаний із міткою: прапорець перемикається щоразу, коли натискається на мітку.
<CheckBox value="boolean" disabled="boolean" t-on-change="onValueChange">
Some Text
</CheckBox>
Props¶
Name |
Тип |
Опис |
|---|---|---|
|
|
якщо true, чекбокс встановлюється, інакше він знімається |
|
|
якщо true, чекбокс вимкнений, інакше він увімкнений |
ColorList¶
Розташування¶
@web/core/colorlist/colorlist
Опис¶
ColorList дозволяє вибрати колір із заздалегідь визначеного списку. За замовчуванням компонент відображає поточний вибраний колір і не розгортається, доки не з’являється props canToggle. Різні пропи можуть змінювати його поведінку, щоб список завжди розгортався або щоб він діяв як перемикач після натискання, відображаючи список доступних кольорів, доки не буде зроблено вибір.
Props¶
Name |
Тип |
Опис |
|---|---|---|
|
|
необов’язково. Чи може список кольорів розгортатися після клацання |
|
|
список кольорів для відображення в компоненті. Кожен колір має унікальний |
|
|
необов’язково. Якщо значення true, список завжди розгортається |
|
|
необов’язково. Якщо значення true, список розгортається за замовчуванням |
|
|
зворотний виклик виконується після вибору кольору |
|
|
необов’язково. Вибраний колір |
id кольорів такі:
Id |
Color |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Dropdown¶
Розташування¶
@web/core/dropdown/dropdown та @web/core/dropdown/dropdown_item
Опис¶
Випадаючі меню – це напрочуд складні компоненти. Вони повинні надавати багато функцій, таких як:
Перемикання списку елементів при кліці
Випадаючі меню прямих братів і сестер: коли одне відкрите, перемикати інші при наведенні курсора
Закривається зовнішнім кліком
За потреби закрити список елементів, коли елемент вибрано
Викликати функцію, коли елемент вибрано
Підтримка випадаючих підменю до будь-якого рівня
SIY: стилізуйте самі
Налаштовувана гаряча клавіша для відкриття/закриття випадаючого списку або вибору елемента випадаючого списку
Навігація за допомогою клавіатури (стрілки, Tab, Shift+Tab, Home, End, Enter та Escape)
Змінює положення щоразу, коли сторінка прокручується або змінюється її розмір
Розумно обрано напрямок відкриття (напрямок справа наліво обробляється автоматично).
Щоб вирішити ці проблеми раз і назавжди, фреймворк Odoo надає набір із двох компонентів: компонент Dropdown (власне випадаючий список) та DropdownItem для кожного елемента у списку елементів.
<Dropdown>
<t t-set-slot="toggler">
<!-- "toggler" slot content is rendered inside a button -->
Click me to toggle the dropdown menu !
</t>
<!-- "default" slot content is rendered inside a div -->
<DropdownItem onSelected="selectItem1">Menu Item 1</DropdownItem>
<DropdownItem onSelected="selectItem2">Menu Item 2</DropdownItem>
</Dropdown>
Props¶
Компонент <Dropdown/> - це просто <div class="dropdown"/> з <button class="dropdown-toggle"/> поруч з div меню (<div class="dropdown-menu"/>). Кнопка відповідає за присутність меню в DOM чи ні.
Dropdown |
Тип |
Опис |
|---|---|---|
|
boolean |
початковий стан відкритого випадаючого меню (за замовчуванням |
|
string |
додатковий клас CSS, застосований до випадаючого меню |
|
string |
додатковий клас CSS, застосований до перемикача |
|
string |
гаряча клавіша для перемикання відкриття за допомогою клавіатури |
|
string |
додати підказку до перемикача |
|
function |
hook для виконання логіки безпосередньо перед відкриттям. Може бути асинхронним. |
|
boolean |
якщо значення true, перемикати/відображати випадаючий список лише при натисканні кнопки (за замовчуванням значення |
|
boolean |
вимкнути (якщо значення true) кнопку випадаючого списку (за замовчуванням значення |
|
string |
вміст атрибута title для |
|
string |
визначає бажану позицію відкриття меню. Напрямок RTL застосовується автоматично. Повинна бути коректною позицією хука usePosition. (за замовчуванням: |
|
|
якщо встановлено значення |
<DropdownItem/> – це просто діапазон (<span class="dropdown-item"/>). Коли <DropdownItem/> вибрано, викликається його властивість onSelected. Якщо ця властивість є методом, переконайтеся, що вона пов’язана, якщо методу потрібно використовувати значення this.
DropdownItem |
Тип |
Опис |
|---|---|---|
|
Функція |
функція, яка буде викликана при виборі елемента з випадаючого списку. |
|
|
коли елемент вибрано, керуйте тим, який батьківський випадаючий список буде закрито: жоден, найближчий або всі (за замовчуванням = |
|
string |
додаткова гаряча клавіша для вибору елемента |
|
string |
якщо його надано, DropdownItem стане |
|
string |
необов’язковий атрибут title, який буде передано кореневому вузлу DropdownItem. (за замовчуванням: не надано) |
|
Об’єкт |
необов’язковий об’єкт, що містить значення, які слід додати до набору даних кореневого елемента. Це можна використовувати для того, щоб елемент було легше знаходити програмно, наприклад, у тестах або турах. |
Технічні примітки¶
Відрендерений DOM структурований так:
<div class="dropdown">
<button class="dropdown-toggle">Click me !</button>
<!-- following <div/> will or won't appear in the DOM depending on the state controlled by the preceding button -->
<div class="dropdown-menu">
<span class="dropdown-item">Menu Item 1</span>
<span class="dropdown-item">Menu Item 2</span>
</div>
</div>
Щоб правильно використовувати компонент <Dropdown/>, вам потрібно заповнити два OWL слоти :
слот
toggler: він містить елементи перемикач вашого випадаючого списку та відображається всередині кнопки випадаючого списку (якщо властивістьtogglerне встановлена наparent),слот
default: він містить елементи самого випадаючого меню та відображається всередині<div class="dropdown-menu"/>. Хоча це не є обов’язковим, зазвичай у слотіmenuє принаймні одинDropdownItem.
Коли кілька випадаючих списків мають один і той самий батьківський елемент у DOM, вони вважаються частиною групи та повідомлятимуть одне одного про зміни свого стану. Це означає, що коли один із цих випадаючих списків відкритий, інші автоматично відкриватимуться при наведенні курсора миші, без необхідності клацання.
Приклад: Випадаючий список прямих братів і сестер¶
Коли натискається один випадаючий перемикач (Файл, Редагувати або Про), інші відкриваються самостійно при наведенні курсора.
<div>
<Dropdown>
<t t-set-slot="toggler">File</t>
<DropdownItem onSelected="() => this.onItemSelected('file-open')">Open</DropdownItem>
<DropdownItem onSelected="() => this.onItemSelected('file-new-document')">New Document</DropdownItem>
<DropdownItem onSelected="() => this.onItemSelected('file-new-spreadsheet')">New Spreadsheet</DropdownItem>
</Dropdown>
<Dropdown>
<t t-set-slot="toggler">Edit</t>
<DropdownItem onSelected="() => this.onItemSelected('edit-undo')">Undo</DropdownItem>
<DropdownItem onSelected="() => this.onItemSelected('edit-redo')">Redo</DropdownItem>
<DropdownItem onSelected="() => this.onItemSelected('edit-find')">Search</DropdownItem>
</Dropdown>
<Dropdown>
<t t-set-slot="toggler">About</t>
<DropdownItem onSelected="() => this.onItemSelected('about-help')">Help</DropdownItem>
<DropdownItem onSelected="() => this.onItemSelected('about-update')">Check update</DropdownItem>
</Dropdown>
</div>
Приклад: Багаторівневий випадаючий список (з t-call)¶
У цьому прикладі показано, як можна створити випадаюче меню File із підменю для піделементів New та Save as....
<t t-name="addon.Dropdown.File">
<Dropdown>
<t t-set-slot="toggler">File</t>
<DropdownItem onSelected="() => this.onItemSelected('file-open')">Open</DropdownItem>
<t t-call="addon.Dropdown.File.New"/>
<DropdownItem onSelected="() => this.onItemSelected('file-save')">Save</DropdownItem>
<t t-call="addon.Dropdown.File.Save.As"/>
</Dropdown>
</t>
<t t-name="addon.Dropdown.File.New">
<Dropdown>
<t t-set-slot="toggler">New</t>
<DropdownItem onSelected="() => this.onItemSelected('file-new-document')">Document</DropdownItem>
<DropdownItem onSelected="() => this.onItemSelected('file-new-spreadsheet')">Spreadsheet</DropdownItem>
</Dropdown>
</t>
<t t-name="addon.Dropdown.File.Save.As">
<Dropdown>
<t t-set-slot="toggler">Save as...</t>
<DropdownItem onSelected="() => this.onItemSelected('file-save-as-csv')">CSV</DropdownItem>
<DropdownItem onSelected="() => this.onItemSelected('file-save-as-pdf')">PDF</DropdownItem>
</Dropdown>
</t>
Приклад: Багаторівневий випадаючий список (вкладений)¶
<Dropdown>
<t t-set-slot="toggler">File</t>
<DropdownItem onSelected="() => this.onItemSelected('file-open')">Open</DropdownItem>
<Dropdown>
<t t-set-slot="toggler">New</t>
<DropdownItem onSelected="() => this.onItemSelected('file-new-document')">Document</DropdownItem>
<DropdownItem onSelected="() => this.onItemSelected('file-new-spreadsheet')">Spreadsheet</DropdownItem>
</Dropdown>
<DropdownItem onSelected="() => this.onItemSelected('file-save')">Save</DropdownItem>
<Dropdown>
<t t-set-slot="toggler">Save as...</t>
<DropdownItem onSelected="() => this.onItemSelected('file-save-as-csv')">CSV</DropdownItem>
<DropdownItem onSelected="() => this.onItemSelected('file-save-as-pdf')">PDF</DropdownItem>
</Dropdown>
</Dropdown>
Приклад: Рекурсивний багаторівневий випадаючий список¶
У цьому прикладі ми рекурсивно викликаємо шаблон для відображення деревоподібної структури.
<t t-name="addon.MainTemplate">
<div>
<t t-call="addon.RecursiveDropdown">
<t t-set="name" t-value="'Main Menu'" />
<t t-set="items" t-value="state.menuItems" />
</t>
</div>
</t>
<t t-name="addon.RecursiveDropdown">
<Dropdown>
<t t-set-slot="toggler"><t t-esc="name"/></t>
<t t-foreach="items" t-as="item" t-key="item.id">
<!-- If this item has no child: make it a <DropdownItem/> -->
<t t-if="!item.childrenTree.length">
<DropdownItem onSelected="() => this.onItemSelected(item)" t-esc="item.name"/>
</t>
<!-- Else: recursively call the current dropdown template. -->
<t t-else="" t-call="addon.RecursiveDropdown">
<t t-set="name" t-value="item.name" />
<t t-set="items" t-value="item.childrenTree" />
</t>
</t>
</t>
</Dropdown>
</t>
Notebook¶
Розташування¶
@web/core/notebook/notebook
Опис¶
Блокнот створений для відображення кількох сторінок у інтерфейсі з вкладками. Вкладки можуть бути розташовані у верхній частині елемента для горизонтального відображення або ліворуч для вертикального розташування.
Існує два способи визначити сторінки Блокноту для створення екземплярів: або за допомогою slot, або передаючи спеціальний props.
Сторінку можна вимкнути за допомогою атрибута isDisabled, встановленого безпосередньо на вузлі слота, або в оголошенні сторінки, якщо Notebook використовується з pages, заданими як властивості. Після вимкнення відповідна вкладка стає сірою та також встановлюється як неактивна.
Props¶
Name |
Тип |
Опис |
|---|---|---|
|
|
необов’язково. Дозволити навігацію за допомогою прив’язок до елементів усередині вкладок, які не видно. |
|
|
необов’язково. Назва класу встановлено в кореневому каталозі компонента. |
|
|
необов’язково. Сторінка |
|
|
необов’язково. Список піктограм, що використовуються на вкладках. |
|
|
необов’язково. Напрямок табуляції - |
|
|
необов’язково. Зворотний виклик виконується після зміни сторінки. |
|
|
необов’язково. Містить список сторінок, які потрібно заповнити з шаблону. |
Example
Перший підхід полягає у встановленні сторінок у слотах компонента.
<Notebook orientation="'vertical'"> <t t-set-slot="page_1" title="'Page 1'" isVisible="true"> <h1>My First Page</h1> <p>It's time to build Owl components. Did you read the documentation?</p> </t> <t t-set-slot="page_2" title="'2nd page'" isVisible="true"> <p>Wise owl's silent flight. Through the moonlit forest deep, guides my path to code</p> </t> </Notebook>Інший спосіб визначення сторінок – це передача властивостей. Це може бути корисним, якщо деякі сторінки мають однакову структуру. Спочатку створіть компонент для кожного шаблону сторінки, який ви можете використовувати.
import { Notebook } from "@web/core/notebook/notebook"; class MyTemplateComponent extends owl.Component { static template = owl.tags.xml` <h1 t-esc="props.title" /> <p t-esc="props.text" /> `; } class MyComponent extends owl.Component { get pages() { return [ { Component: MyTemplateComponent, title: "Page 1", props: { title: "My First Page", text: "This page is not visible", }, }, { Component: MyTemplateComponent, id: "page_2", title: "Page 2", props: { title: "My second page", text: "You're at the right place!", }, }, ] } } MyComponent.template = owl.tags.xml` <Notebook defaultPage="'page_2'" pages="pages" /> `;
Обидва приклади наведено тут:
Пейджер¶
Розташування¶
@web/core/pager/pager
Опис¶
Пейджер – це невеликий компонент для обробки пагінації. Сторінка визначається параметрами offset та limit (розмір сторінки). Він відображає поточну сторінку та total кількість елементів, наприклад, «9-12 / 20». У попередньому прикладі offset дорівнює 8, limit – 4, а total – 20. Він має дві кнопки («Попередній» та «Наступний») для навігації між сторінками.
Примітка
Пейджер можна використовувати будь-де, але його основне застосування — на панелі керування. Дивіться хук usePager для керування пейджером панелі керування.
<Pager offset="0" limit="80" total="50" onUpdate="doSomething" />
Props¶
Name |
Тип |
Опис |
|---|---|---|
|
|
Індекс першого елемента сторінки. Він починається з 0, але пейджер відображає |
|
|
Розмір сторінки. Сума |
|
|
Загальна кількість елементів, яких може досягти сторінка. |
|
|
Функція, яка викликається, коли сторінку змінює пейджер. Ця функція може бути асинхронною, пейджер не можна редагувати, поки вона виконується. |
|
|
Дозволяє клацнути на поточній сторінці для її редагування (за замовчуванням |
|
|
Прив’язує клавішу доступу |
Розташування¶
@web/core/select_menu/select_menu
Опис¶
Цей компонент можна використовувати, коли вам потрібно зробити більше, ніж просто використовувати вбудований елемент select. Ви можете визначити власний шаблон опцій, що дозволить пошук між вашими опціями, або згрупувати їх у підрозділи.
Примітка
Віддавайте перевагу нативному HTML-елементу select, оскільки він за замовчуванням забезпечує функції спеціальних можливостей та має кращий інтерфейс користувача на мобільних пристроях. Цей компонент розроблено для використання в складніших випадках використання, щоб подолати обмеження нативного елемента.
Props¶
Name |
Тип |
Опис |
|---|---|---|
|
|
необов’язково. Список |
|
|
необов’язково. Назва класу встановлюється в кореневому елементі компонента SelectMenu. |
|
|
необов’язково. Список |
|
|
необов’язково. Увімкнути множинний вибір. Коли множинний вибір увімкнено, вибрані значення відображаються як tag у вхідних даних SelectMenu. |
|
|
необов’язково. назва класу встановлена на кнопці-перемикачі. |
|
|
необов’язково. Чи можна скасувати вибір вибраного значення. |
|
|
необов’язково. Чи відображається поле пошуку у випадаючому списку. |
|
|
необов’язково. Текст, що відображається як заповнювач поля пошуку. |
|
|
необов’язково. Поточне вибране значення. Може бути будь-якого типу. |
|
|
необов’язково. Зворотний виклик виконується, коли вибрано опцію. |
Форма choice така:
value– це фактичне значення вибору. Зазвичай це технічний рядок, але може бути будь-якого типу.
label– це текст, що відображається, пов’язаний з опцією. Зазвичай це більш зрозумілий та перекладенийstring.
Форма group така:
choices– це списокchoice, які потрібно відобразити для цієї групи.
label– це відображений текст, пов’язаний із групою. Церядок, що відображається у верхній частині групи.
Example
У наступному прикладі SelectMenu відображатиме чотири варіанти. Один з них відображається поверх опцій, оскільки з ним не пов’язано жодних груп, але інші розділені міткою їхньої групи.
import { SelectMenu } from "@web/core/select_menu/select_menu";
class MyComponent extends owl.Component {
get choices() {
return [
{
value: "value_1",
label: "First value"
}
]
}
get groups() {
return [
{
label: "Group A",
choices: [
{
value: "value_2",
label: "Second value"
},
{
value: "value_3",
label: "Third value"
}
]
},
{
label: "Group B",
choices: [
{
value: "value_4",
label: "Fourth value"
}
]
}
]
}
}
MyComponent.template = owl.tags.xml`
<SelectMenu
choices="choices"
groups="groups"
value="'value_2'"
/>
`;
Ви також можете налаштувати зовнішній вигляд перемикача та встановити власний шаблон для варіантів вибору, використовуючи відповідні слоти компонентів.
MyComponent.template = owl.tags.xml`
<SelectMenu
choices="choices"
groups="groups"
value="'value_2'"
>
Make a choice!
<t t-set-slot="choice" t-slot-scope="choice">
<span class="coolClass" t-esc="'👉 ' + choice.data.label + ' 👈'" />
</t>
</SelectMenu>
`;
Коли SelectMenu використовується з множинним вибором, властивості value повинні бути масивом Array, що містить значення вибраних варіантів.
Для більш складних випадків використання ви можете налаштувати нижню частину випадаючого списку, використовуючи слот bottomArea. Тут ми вибираємо відображення кнопки з відповідним значенням, встановленим у полі пошуку.
MyComponent.template = owl.tags.xml`
<SelectMenu
choices="choices"
>
<span class="select_menu_test">Select something</span>
<t t-set-slot="bottomArea" t-slot-scope="select">
<div t-if="select.data.searchValue">
<button class="btn text-primary" t-on-click="() => this.onCreate(select.data.searchValue)">
Create this article "<i t-esc="select.data.searchValue" />"
</button>
</div>
</t>
</SelectMenu>
`;
Розташування¶
@web/core/tags_list/tags_list
Опис¶
Цей компонент може відображати список тегів у вигляді округлених таблиць. Ці теги можуть або просто перераховувати кілька значень, або бути редагованими, що дозволяє видаляти елементи. Можна обмежити кількість відображаних елементів за допомогою властивостей itemsVisible. Якщо список перевищує це обмеження, кількість додаткових елементів відображається в колі поруч з останнім тегом.
Props¶
Name |
Тип |
Опис |
|---|---|---|
|
|
необов’язково. Чи відображається тег як значок. |
|
|
необов’язково. Чи відображається тег із текстом чи ні. |
|
|
необов’язково. Обмеження видимих тегів у списку. |
|
|
список елементів |
Форма tag така:
colorIndex– це необов’язковий ідентифікатор кольору.
icon- це необов’язкова піктограма, що відображається безпосередньо перед відображеним текстом.
id– це унікальний ідентифікатор тегу.
img- це необов’язкове зображення, яке відображається в колі, безпосередньо перед відображеним текстом.
onClick- це необов’язковий зворотний виклик, який можна надати елементу. Це дозволяє батьківському елементу обробляти будь-яку функціональність залежно від тегу, на який було натиснуто.
onDelete- це необов’язковий зворотний виклик, який можна передати елементу. Це робить можливим видалення елемента зі списку тегів і має оброблятися батьківським елементом.
text– це відображенийstring, пов’язаний з тегом.
Example
У наступному прикладі компонент TagsList використовується для відображення кількох тегів. Розробник повинен з батьківського компонента керувати тим, що станеться при натисканні тегу або кнопки видалення.
import { TagsList } from "@web/core/tags_list/tags_list";
class Parent extends Component {
setup() {
this.tags = [{
id: "tag1",
text: "Earth"
}, {
colorIndex: 1,
id: "tag2",
text: "Wind",
onDelete: () => {...}
}, {
colorIndex: 2,
id: "tag3",
text: "Fire",
onClick: () => {...},
onDelete: () => {...}
}];
}
}
Parent.components = { TagsList };
Parent.template = xml`<TagsList tags="tags" />`;
Залежно від атрибутів, наданих кожному тегу, їхній зовнішній вигляд та поведінка будуть відрізнятися.