Thành phần cú

Khung Javascript của SoOn sử dụng khung thành phần tùy chỉnh có tên Owl. Nó là một hệ thống thành phần khai báo, lấy cảm hứng từ Vue và React. Các thành phần được xác định bằng cách sử dụng QWeb templates, được bổ sung thêm một số chỉ thị cụ thể của Owl. Tài liệu Owl chính thức chứa tài liệu tham khảo đầy đủ và hướng dẫn.

Quan trọng

Mặc dù mã có thể được tìm thấy trong mô-đun web nhưng nó được duy trì từ một kho lưu trữ GitHub riêng biệt. Do đó, mọi sửa đổi đối với Owl phải được thực hiện thông qua yêu cầu kéo trên https://github.com/odoo/owl.

Ghi chú

Hiện tại, tất cả các phiên bản SoOn (bắt đầu từ phiên bản 14) đều có chung phiên bản Owl.

Sử dụng các thành phần Owl

Tài liệu về Owl đã có tài liệu chi tiết về khung Owl nên trang này sẽ chỉ cung cấp thông tin cụ thể về SoOn. Nhưng trước tiên, hãy xem cách chúng ta có thể tạo một thành phần đơn giản trong SoOn.

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>`;

Ví dụ này cho thấy Owl có sẵn dưới dạng thư viện trong không gian tên chung dưới dạng owl: nó có thể được sử dụng đơn giản giống như hầu hết các thư viện trong SoOn. Lưu ý rằng ở đây chúng tôi đã xác định mẫu là thuộc tính tĩnh nhưng không sử dụng từ khóa static, từ khóa này không có sẵn trong một số trình duyệt (mã javascript SoOn phải tuân thủ Ecmascript 2019).

Ở đây chúng tôi xác định mẫu trong mã javascript với sự trợ giúp của trình trợ giúp xml. Tuy nhiên, nó chỉ hữu ích khi bắt đầu. Trong thực tế, các mẫu trong SoOn phải được xác định trong tệp xml để có thể dịch chúng. Trong trường hợp đó, thành phần chỉ nên xác định tên mẫu.

Trong thực tế, hầu hết các thành phần nên xác định 2 hoặc 3 tệp, nằm ở cùng một vị trí: tệp javascript (my_comComponent.js), tệp mẫu (my_comComponent.xml) và tùy chọn là tệp scss (hoặc css) (` my_comComponent.scss`). Những tập tin này sau đó sẽ được thêm vào một số gói nội dung. Khung web sẽ đảm nhiệm việc tải các tệp javascript/css và tải các mẫu vào Owl.

Đây là cách xác định thành phần trên:

const { useState } = owl.hooks;

class MyComponent extends Component {
    ...
}
MyComponent.template = 'myaddon.MyComponent';

Và mẫu hiện nằm trong tệp xml tương ứng:

<?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>

Ghi chú

Tên mẫu phải tuân theo quy ước addon_name.ComponentName.

Xem thêm

Thực hành tốt nhất

Trước hết, các thành phần là các lớp nên chúng có một hàm tạo. Nhưng hàm tạo là các phương thức đặc biệt trong javascript không thể ghi đè được theo bất kỳ cách nào. Vì đây đôi khi là một mẫu hữu ích trong SoOn nên chúng ta cần đảm bảo rằng không có thành phần nào trong SoOn trực tiếp sử dụng phương thức khởi tạo. Thay vào đó, các thành phần nên sử dụng phương thức 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
    }
}

Một phương pháp hay khác là sử dụng quy ước nhất quán cho tên mẫu: addon_name.ComponentName. Điều này ngăn ngừa xung đột tên giữa các addon odoo.

Danh sách tham khảo

Ứng dụng khách web SoOn được xây dựng với các thành phần Owl. Để dễ dàng hơn, khung javascript của SoOn cung cấp một bộ các thành phần chung có thể được sử dụng lại trong một số trường hợp phổ biến, chẳng hạn như menu thả xuống, hộp kiểm hoặc công cụ chọn ngày. Trang này giải thích cách sử dụng các thành phần chung này.

Tên kỹ thuật

Mô tả ngắn

ActionSwiper

một thành phần vuốt để thực hiện các hành động khi vuốt bằng cảm ứng

CheckBox

một thành phần hộp kiểm đơn giản có nhãn bên cạnh

ColorList

một danh sách các màu sắc để lựa chọn

Thả xuống

thả xuống đầy đủ tính năng

Notebook

một thành phần để điều hướng giữa các trang bằng cách sử dụng các tab

Máy nhắn tin

một thành phần nhỏ để xử lý phân trang

SelectMenu

một thành phần thả xuống để chọn giữa các tùy chọn khác nhau

TagsList

danh sách các thẻ được hiển thị trong các viên thuốc tròn

Hành động quét

Vị trí

@web/core/action_swiper/action_swiper

Sự miêu tả

Đây là thành phần có thể thực hiện các hành động khi một phần tử được vuốt theo chiều ngang. Thanh vuốt đang bao bọc phần tử mục tiêu để thêm hành động vào phần tử đó. Hành động được thực thi sau khi người dùng đã thả thanh vuốt đi qua một phần chiều rộng của nó.

<ActionSwiper onLeftSwipe="Object" onRightSwipe="Object">
  <SomeElement/>
</ActionSwiper>

Cách đơn giản nhất để sử dụng thành phần này là sử dụng nó xung quanh phần tử mục tiêu của bạn trực tiếp trong mẫu xml như được hiển thị ở trên. Nhưng đôi khi, bạn có thể muốn mở rộng phần tử hiện có và không muốn sao chép mẫu. Có thể làm điều đó.

Nếu bạn muốn mở rộng hành vi của một phần tử hiện có, bạn phải đặt phần tử đó vào bên trong bằng cách gói nó trực tiếp. Ngoài ra, bạn có thể thêm các đạo cụ có điều kiện để quản lý thời điểm phần tử có thể vuốt được, hoạt ảnh của phần tử đó và phần tối thiểu cần vuốt để thực hiện hành động.

Bạn có thể sử dụng thành phần này để tương tác dễ dàng với các bản ghi, tin nhắn, mục trong danh sách, v.v.

Ví dụ về cách sử dụng ActionSwiper

Ví dụ sau tạo thành phần ActionSwiper cơ bản. Ở đây, thao tác vuốt được bật theo cả hai hướng.

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

Ghi chú

Các hành động được hoán vị khi sử dụng ngôn ngữ từ phải sang trái (RTL).

đạo cụ

Tên

Kiểu

Sự miêu tả

hoạt hìnhOnMove

Boolean

boolean tùy chọn để xác định xem có hiệu ứng dịch trong quá trình vuốt hay không

loại hoạt hình

Chuỗi

hoạt ảnh tùy chọn được sử dụng sau khi thao tác vuốt kết thúc (bật lên hoặc chuyển tiếp)

onLeftSwipe

Đối tượng

nếu có, bạn có thể vuốt thao tác gạt sang trái

onRightSwipe

Đối tượng

nếu có, bạn có thể vuốt thao tác gạt sang phải

tỷ lệ khoảng cách vuốt

Số

tỷ lệ chiều rộng tối thiểu tùy chọn phải được vuốt để thực hiện hành động

Bạn có thể sử dụng cả đạo cụ onLeftSwipeonRightSwipe cùng một lúc.

Đối tượng được sử dụng để vuốt sang trái/phải phải chứa:

  • action, là Hàm có thể gọi được dùng làm lệnh gọi lại. Sau khi hoàn tất thao tác vuốt theo hướng đã cho, hành động đó sẽ được thực hiện.

  • icon là lớp biểu tượng được sử dụng, thường để thể hiện hành động. Nó phải là một chuỗi.

  • bgColor là màu nền, được dùng để trang trí cho hành động. có thể là một trong màu ngữ cảnh của bootstrap sau đây (danger, info, secondary, success hoặc ` cảnh báo`).

Những giá trị đó phải được đưa ra để xác định hành vi và khía cạnh trực quan của thao tác vuốt.

Ví dụ: Mở rộng các thành phần hiện có

Trong ví dụ sau, bạn có thể sử dụng xpath để bao bọc một phần tử hiện có trong thành phần ActionSwiper. Ở đây, một thanh gạt đã được thêm vào để đánh dấu thư là đã đọc trong thư.

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

Hộp kiểm

Vị trí

@web/core/hộp kiểm/hộp kiểm

Sự miêu tả

Đây là thành phần hộp kiểm đơn giản có nhãn bên cạnh. Hộp kiểm được liên kết với nhãn: hộp kiểm được bật bất cứ khi nào nhãn được nhấp vào.

<CheckBox value="boolean" disabled="boolean" t-on-change="onValueChange">
  Some Text
</CheckBox>

đạo cụ

Tên

Kiểu

Sự miêu tả

giá trị

boolean

nếu đúng thì hộp kiểm sẽ được chọn, nếu không thì nó sẽ bị bỏ chọn

bị hiệu hóa

boolean

nếu đúng, hộp kiểm sẽ bị tắt, nếu không thì nó sẽ được bật

Danh sách màu

Vị trí

@web/core/danh sách màu/danh sách màu

Sự miêu tả

ColorList cho phép bạn chọn một màu từ danh sách được xác định trước. Theo mặc định, thành phần này hiển thị màu được chọn hiện tại và không thể mở rộng cho đến khi có đạo cụ canToggle. Các đạo cụ khác nhau có thể thay đổi hành vi của nó, để luôn mở rộng danh sách hoặc làm cho nó hoạt động như một công cụ chuyển đổi sau khi được nhấp vào, để hiển thị danh sách các màu có sẵn cho đến khi lựa chọn được chọn.

đạo cụ

Tên

Kiểu

Sự miêu tả

thểChuyển đổi

boolean

không bắt buộc. Liệu danh sách màu có thể mở rộng danh sách khi nhấp chuột hay không

màu sắc

mảng

danh sách các màu sẽ hiển thị trong thành phần. Mỗi màu có một id duy nhất

lựcMở rộng

boolean

không bắt buộc. Nếu đúng, danh sách luôn được mở rộng

được mở rộng

boolean

không bắt buộc. Nếu đúng, danh sách sẽ được mở rộng theo mặc định

onColorSelected

chức năng

gọi lại được thực hiện khi màu được chọn

Màu đã chọn

số

không bắt buộc. Màu id được chọn

Màu id như sau:

Nhận dạng

Màu sắc

0

Không màu

1

Đỏ

2

Cam

3

Vàng

4

Màu xanh nhạt

5

Tím đậm

6

Hồng hồi

7

`Màu xanh vừa'

8

Màu xanh đậm

9

Fuchsia

12

Xanh

11

Tím

Vị trí

@web/core/dropdown/dropdown@web/core/dropdown/dropdown_item

Sự miêu tả

Dropdowns là thành phần phức tạp đáng ngạc nhiên. Họ cần cung cấp nhiều tính năng như:

  • Chuyển đổi danh sách mục khi nhấp chuột

  • Danh sách thả xuống trực tiếp của anh chị em: khi một cái được mở, hãy chuyển đổi những cái khác khi di chuột

  • Đóng khi nhấp chuột bên ngoài

  • Tùy chọn đóng danh sách mục khi chọn một mục

  • Gọi một hàm khi mục được chọn

  • Hỗ trợ thả xuống phụ, ở mọi cấp độ

  • SIY: tự tạo phong cách cho mình

  • Phím nóng có thể định cấu hình để mở/đóng danh sách thả xuống hoặc chọn mục thả xuống

  • Điều hướng bằng bàn phím (mũi tên, tab, shift+tab, trang chủ, kết thúc, nhập và thoát)

  • Tự định vị lại bất cứ khi nào trang cuộn hoặc được thay đổi kích thước

  • Chọn hướng thông minh sẽ mở (hướng từ phải sang trái được xử lý tự động).

Để giải quyết những vấn đề này một lần và mãi mãi, khung SoOn cung cấp một bộ gồm hai thành phần: thành phần Dropdown (danh sách thả xuống thực tế) và DropdownItem, cho mỗi thành phần trong danh sách mục.

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

đạo cụ

Thành phần <Dropdown/> chỉ đơn giản là một <div class="dropdown"/><button class="dropdown-toggle"/> bên cạnh div menu (<div class="dropdown- thực đơn"/>). Nút này chịu trách nhiệm cho việc menu có trong DOM hay không.

Thả xuống

Kiểu

Sự miêu tả

bắt đầuMở

boolean

trạng thái mở thả xuống ban đầu (mặc định là false)

menuClass

sợi dây

lớp css bổ sung được áp dụng cho menu thả xuống <div class="dropdown-menu"/>

togglerClass

sợi dây

lớp css bổ sung được áp dụng cho trình chuyển đổi <button class="dropdown-toggle"/>

phím nóng

sợi dây

phím nóng để chuyển đổi mở thông qua bàn phím

chú giải công cụ

sợi dây

thêm chú giải công cụ vào nút chuyển đổi

trướcMở

chức năng

hook để thực thi logic ngay trước khi mở. Có thể không đồng bộ.

chỉ thủ công

boolean

nếu đúng, chỉ chuyển đổi menu thả xuống khi nhấp vào nút (mặc định là false)

bị hiệu hóa

boolean

vô hiệu hóa (nếu đúng) nút thả xuống (mặc định là false)

tiêu đề

sợi dây

nội dung thuộc tính tiêu đề cho <button class="dropdown-toggle"/> (mặc định: không có)

vị trí

sợi dây

xác định vị trí mở menu mong muốn. Hướng RTL được tự động áp dụng. Phải là vị trí Hooks usePosition hợp lệ. (mặc định: bắt đầu từ dưới)

chuyển đổi

"cha mẹ" hoặc không xác định

khi được đặt thành "parent" thì <button class="dropdown-toggle"/> không được hiển thị (do đó, khe toggler bị bỏ qua) và tính năng chuyển đổi được xử lý bởi nút cha (ví dụ: trường hợp sử dụng: trục tế bào). (mặc định: không xác định)

<DropdownItem/> chỉ đơn giản là một span (<span class="dropdown-item"/>). Khi một <DropdownItem/> được chọn, nó sẽ gọi prop onSelected của nó. Nếu prop này là một phương thức, hãy đảm bảo rằng nó bị ràng buộc nếu phương thức đó cần sử dụng giá trị this.

Mục thả xuống

Kiểu

Sự miêu tả

onSelected

Chức năng

một hàm sẽ được gọi khi mục thả xuống được chọn.

Chế độ đóng cha mẹ

không | gần nhất | tất cả

khi mục được chọn, hãy kiểm soát danh sách thả xuống gốc nào sẽ bị đóng: không có, gần nhất hoặc tất cả (mặc định = all)

phím nóng

sợi dây

phím nóng tùy chọn để chọn mục

href

sợi dây

nếu được cung cấp thì DropdownItem sẽ trở thành <a href="value" class="dropdown-item"/> thay vì <span class="dropdown-item"/>. (mặc định: không được cung cấp)

tiêu đề

sợi dây

thuộc tính tiêu đề tùy chọn sẽ được chuyển đến nút gốc của DropdownItem. (mặc định: không được cung cấp)

tập dữ liệu

Sự vật

đối tượng tùy chọn chứa các giá trị cần được thêm vào tập dữ liệu của phần tử gốc. Bạn có thể sử dụng tùy chọn này để phần tử dễ dàng được tìm thấy hơn theo chương trình, chẳng hạn như trong các bài kiểm tra hoặc chuyến tham quan.

Ghi chú kỹ thuật

DOM được hiển thị có cấu trúc như thế này:

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

Để sử dụng đúng thành phần <Dropdown/>, bạn cần điền hai vị trí OWL :

  • Khe toggler: nó chứa các phần tử toggler của danh sách thả xuống của bạn và được hiển thị bên trong button thả xuống (trừ khi prop toggler được đặt thành parent),

  • Khe default: nó chứa các phần tử của chính menu thả xuống và được hiển thị bên trong <div class="dropdown-menu"/>. Mặc dù không bắt buộc nhưng thường có ít nhất một DropdownItem bên trong khe menu.

Khi một số danh sách thả xuống chia sẻ cùng một phần tử gốc trong DOM thì chúng được coi là một phần của một nhóm và sẽ thông báo cho nhau về những thay đổi trạng thái của chúng. Điều này có nghĩa là khi một trong những danh sách thả xuống này được mở, những danh sách khác sẽ tự động mở khi di chuột mà không cần nhấp chuột.

Ví dụ: Danh sách thả xuống anh chị em trực tiếp

Khi nhấp vào một trình chuyển đổi thả xuống (Tệp , Chỉnh sửa hoặc Giới thiệu), các trình chuyển đổi khác sẽ tự mở khi di chuột.

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

Ví dụ: Thả xuống đa cấp (với t-call)

Ví dụ này cho thấy cách người ta có thể tạo một menu thả xuống File, với các menu con cho các phần tử phụ NewSave 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>

Ví dụ: Thả xuống đa cấp (lồng nhau)

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

Ví dụ: Thả xuống đa cấp đệ quy

Trong ví dụ này, chúng tôi gọi đệ quy một mẫu để hiển thị cấu trúc dạng cây.

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

Sổ tay

Vị trí

@web/core/notebook/notebook

Sự miêu tả

Notebook được thiết kế để hiển thị nhiều trang trong giao diện theo thẻ. Các tab có thể được đặt ở đầu phần tử để hiển thị theo chiều ngang hoặc ở bên trái để bố cục theo chiều dọc.

Có hai cách để xác định các trang Notebook của bạn cần khởi tạo, bằng cách sử dụng slot' hoặc bằng cách chuyển một props chuyên dụng.

Một trang có thể bị vô hiệu hóa bằng thuộc tính isDisabled, được đặt trực tiếp trên nút vị trí hoặc trong khai báo trang, nếu Notebook được sử dụng với pages được cung cấp làm đạo cụ. Sau khi bị tắt, tab tương ứng sẽ chuyển sang màu xám và được đặt ở trạng thái không hoạt động.

đạo cụ

Tên

Kiểu

Sự miêu tả

neo

đối tượng

không bắt buộc. Cho phép điều hướng neo tới các thành phần bên trong các tab không hiển thị.

tên lớp

chuỗi

không bắt buộc. Tên lớp được đặt trên thư mục gốc của thành phần.

Trang mặc định

chuỗi

không bắt buộc. Trang id sẽ hiển thị theo mặc định.

biểu tượng

mảng

không bắt buộc. Danh sách các biểu tượng được sử dụng trong các tab.

định hướng

chuỗi

không bắt buộc. Hướng của tab là ngang hay dọc.

onPageUpdate

chức năng

không bắt buộc. Lệnh gọi lại được thực hiện khi trang đã thay đổi.

trang

mảng

không bắt buộc. Chứa danh sách trang để điền từ một mẫu.

Example

Cách tiếp cận đầu tiên là đặt các trang vào các vị trí của thành phần.

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

Cách khác để xác định trang của bạn là chuyển các đạo cụ. Điều này có thể hữu ích nếu một số trang có cùng cấu trúc. Đầu tiên hãy tạo một thành phần cho mỗi mẫu trang mà bạn có thể sử dụng.

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" />
`;

Cả hai ví dụ đều được hiển thị ở đây:

Ví dụ về bố cục dọc và ngang

Máy nhắn tin

Vị trí

@web/core/pager/pager

Sự miêu tả

Pager là một thành phần nhỏ để xử lý phân trang. Một trang được xác định bởi offsetlimit (kích thước của trang). Nó hiển thị trang hiện tại và tổng số phần tử, ví dụ: "9-12 / 20". Trong ví dụ trước, offset là 8, giới hạn là 4 và tổng là 20. Nó có hai nút ("Trước" và "Tiếp theo") để điều hướng giữa các trang.

Ghi chú

Máy nhắn tin có thể được sử dụng ở bất cứ đâu nhưng công dụng chính của nó là trong bảng điều khiển. Xem hook usePager để thao tác với máy nhắn tin của bảng điều khiển.

<Pager offset="0" limit="80" total="50" onUpdate="doSomething" />

đạo cụ

Tên

Kiểu

Sự miêu tả

đắp

số

Chỉ mục của phần tử đầu tiên của trang. Nó bắt đầu bằng 0 nhưng máy nhắn tin hiển thị offset + 1.

giới hạn

số

Kích thước của trang. Tổng của offsetlimit tương ứng với chỉ mục của phần tử cuối cùng của trang.

tổng

số

Tổng số phần tử mà trang có thể tiếp cận.

onUpdate

chức năng

Hàm được gọi khi trang được sửa đổi bởi máy nhắn tin. Chức năng này có thể không đồng bộ, không thể chỉnh sửa máy nhắn tin trong khi chức năng này đang thực thi.

thể chỉnh sửa

boolean

Cho phép nhấp vào trang hiện tại để chỉnh sửa nó (true theo mặc định).

vớiAccessKey

boolean

Liên kết khóa truy cập p trên nút trang trước và n ở trang tiếp theo (true theo mặc định).

ChọnMenu

Vị trí

@web/core/select_menu/select_menu

Sự miêu tả

Thành phần này có thể được sử dụng khi bạn muốn làm nhiều việc hơn là sử dụng phần tử select gốc. Bạn có thể xác định mẫu tùy chọn của riêng mình, cho phép tìm kiếm giữa các tùy chọn hoặc nhóm chúng thành các phần phụ.

Ghi chú

Ưu tiên phần tử select HTML gốc vì nó cung cấp các tính năng trợ năng theo mặc định và có giao diện người dùng tốt hơn trên thiết bị di động. Thành phần này được thiết kế để sử dụng cho các trường hợp sử dụng phức tạp hơn, nhằm khắc phục các hạn chế của phần tử gốc.

đạo cụ

Tên

Kiểu

Sự miêu tả

lựa chọn

mảng

không bắt buộc. Danh sách lựa chọn sẽ hiển thị trong danh sách thả xuống.

lớp

chuỗi

không bắt buộc. Tên lớp được đặt trên thư mục gốc của thành phần SelectMenu.

nhóm

mảng

không bắt buộc. Danh sách nhóm, chứa lựa chọn để hiển thị trong danh sách thả xuống.

đa lựa chọn

boolean

không bắt buộc. Kích hoạt nhiều lựa chọn. Khi bật nhiều lựa chọn, các giá trị đã chọn sẽ được hiển thị dưới dạng tag trong đầu vào SelectMenu.

togglerClass

chuỗi

không bắt buộc. tên lớp được đặt trên nút chuyển đổi.

bắt buộc

boolean

không bắt buộc. Liệu giá trị đã chọn có thể được bỏ chọn hay không.

thể tìm kiếm

boolean

không bắt buộc. Liệu hộp tìm kiếm có hiển thị trong danh sách thả xuống hay không.

trình giữ chỗ tìm kiếm

chuỗi

không bắt buộc. Văn bản được hiển thị dưới dạng phần giữ chỗ của hộp tìm kiếm.

giá trị

bất kỳ

không bắt buộc. Giá trị được chọn hiện tại. Nó có thể thuộc bất kỳ loại nào.

onSelect

chức năng

không bắt buộc. Lệnh gọi lại được thực hiện khi một tùy chọn được chọn.

Hình dạng của một lựa chọn như sau:

  • value là giá trị thực của lựa chọn. Nó thường là một chuỗi kỹ thuật, nhưng có thể thuộc loại bất kỳ.

  • nhãn là văn bản hiển thị được liên kết với tùy chọn. Đây thường là một chuỗi thân thiện và được dịch hơn.

Hình dạng của một nhóm như sau:

  • lựa chọn là danh sách lựa chọn để hiển thị cho nhóm này.

  • nhãn là văn bản hiển thị được liên kết với nhóm. Đây là một chuỗi được hiển thị ở đầu nhóm.

Example

Trong ví dụ sau, SelectMenu sẽ hiển thị bốn lựa chọn. Một trong số chúng được hiển thị ở trên cùng của các tùy chọn, vì không có nhóm nào được liên kết với nó, nhưng các nhóm còn lại được phân tách bằng nhãn của nhóm của chúng.

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'"
  />
`;

Bạn cũng có thể tùy chỉnh giao diện của nút chuyển đổi và đặt mẫu tùy chỉnh cho các lựa chọn bằng cách sử dụng slot' thành phần thích hợp.

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>
`;
Ví dụ về cách sử dụng và tùy chỉnh SelectMenu

Khi SelectMenu được sử dụng với nhiều lựa chọn, đạo cụ value phải là một Array chứa các giá trị của các lựa chọn đã chọn.

Ví dụ về SelectMenu được sử dụng với nhiều lựa chọn

Đối với các trường hợp sử dụng nâng cao hơn, bạn có thể tùy chỉnh khu vực dưới cùng của danh sách thả xuống bằng cách sử dụng khe bottomArea. Ở đây, chúng tôi chọn hiển thị một nút có giá trị tương ứng được đặt trong đầu vào tìm kiếm.

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>
`;
Ví dụ về tùy chỉnh vùng dưới cùng của SelectMenu

ThẻDanh sách

Vị trí

@web/core/tags_list/tags_list

Sự miêu tả

Thành phần này có thể hiển thị danh sách các thẻ trong các viên thuốc được làm tròn. Các thẻ đó có thể chỉ liệt kê một vài giá trị hoặc có thể chỉnh sửa được, cho phép xóa các mục. Có thể giới hạn số lượng mục được hiển thị bằng cách sử dụng đạo cụ itemsVisible. Nếu danh sách dài hơn giới hạn này, số lượng mục bổ sung sẽ được hiển thị trong vòng tròn bên cạnh thẻ cuối cùng.

đạo cụ

Tên

Kiểu

Sự miêu tả

huy hiệu hiển thị

boolean

không bắt buộc. Liệu thẻ có được hiển thị dưới dạng huy hiệu hay không.

văn bản hiển thị

boolean

không bắt buộc. Thẻ có được hiển thị cùng với văn bản hay không.

itemCó thể nhìn thấy

số

không bắt buộc. Giới hạn thẻ hiển thị trong danh sách.

thẻ

mảng

danh sách các phần tử của tag được cấp cho thành phần.

Hình dạng của một tag như sau:

  • colorIndex là id màu tùy chọn.

  • icon là một biểu tượng tùy chọn được hiển thị ngay trước văn bản được hiển thị.

  • id là mã định danh duy nhất cho thẻ.

  • img là một hình ảnh tùy chọn được hiển thị trong vòng tròn, ngay trước văn bản được hiển thị.

  • onClick là lệnh gọi lại tùy chọn có thể được cung cấp cho phần tử. Điều này cho phép phần tử gốc xử lý bất kỳ chức năng nào tùy thuộc vào thẻ được nhấp vào.

  • onDelete là một lệnh gọi lại tùy chọn có thể được cấp cho phần tử. Điều này làm cho việc xóa mục khỏi danh sách thẻ có thể thực hiện được và phải được xử lý bởi phần tử gốc.

  • textstring được hiển thị liên kết với thẻ.

Example

Trong ví dụ tiếp theo, thành phần TagsList được sử dụng để hiển thị nhiều thẻ. Nhà phát triển có quyền xử lý từ cấp độ gốc điều gì sẽ xảy ra khi thẻ được nhấn hoặc khi nhấp vào nút xóa.

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" />`;

Tùy thuộc vào các thuộc tính được cung cấp cho mỗi thẻ, hình thức và hành vi của chúng sẽ khác nhau.

Ví dụ về TagsList sử dụng các đạo cụ và thuộc tính khác nhau