Odoo Javascript 框架使用称为 Owl 的自定义组件框架。它是一个声明式组件系统,受到 Vue 和 React 的粗略启发。组件使用QWeb 模板定义,并添加了一些 Owl 特定指令。
注:
目前,所有 Odoo 版本(从版本 14 开始)共享相同的 Owl 版本。
1、使用 Owl 组件

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 关键字,这在某些浏览器中不可用(Odoo javascript 代码应符合 Ecmascript 2019),模板只能有一个div的根节点。
*在 javascript 代码中定义了模板xml 。但是,它仅在定义时起作用。在具体开发过程中,Odoo 中的模板应该定义在一个 xml 文件中,这样它们就可以被翻译。也就是说,组件应该只定义模板名称。
*在开发时,大多数组件应该定义 2 或 3 个文件,位于同一位置:一个 javascript 文件 ( my_component.js)、一个模板文件 ( my_component.xml) 和可选的 scss(或 css)文件 ( my_component.scss)。然后应将这些文件添加到某些资产包中。Web 框架将负责加载 javascript/css 文件,并将模板加载到 Owl 中。

以下是上述组件的定义方式:

const { useState } = owl.hooks;class MyComponent extends Component {...
}
MyComponent.template = 'myaddon.MyComponent';

模板是位于xml中的qweb :

<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve"><t t-name="myaddon.MyComponent" owl="1"><div t-on-click="increment"><t t-esc="state.value"/></div>
</t></templates>

Odoo 代码还没有完全用 Owl 编写,因此它需要一种方法来区分 Owl 模板(新代码)和旧模板(用于组件)之间的区别。为了以向后兼容的方式做到这一点,所有新模板都应该使用owl属性设置为 1 来定义。
注:
*不要忘记owl="1"在您的猫头鹰模板中设置!
*模板名称应遵循约定addon_name.ComponentName。
2、最佳实践
首先,组件是类,所以它们有一个构造函数。但是构造函数是 javascript 中的特殊方法,不能以任何方式覆盖。由于这是 Odoo 中偶尔有用的模式,我们需要确保 Odoo 中没有任何组件直接使用构造函数方法。相反,组件应该使用以下 setup方法:
// 正确:

class MyComponent extends Component {setup() {// initialize component here}
}//不正确,不要这样作。
class IncorrectComponent extends Component {constructor(parent, props) {// initialize component here}
}

另一个推荐的做法是对模板名称使用一致的约定: addon_name.ComponentName. 这可以防止 odoo 模块之间的名称冲突。
3、参考文档列表
Odoo Web 客户端是使用Owl组件构建的。为了使它更容易,Odoo javascript 框架提供了一套通用组件,可以在一些常见情况下重用,例如下拉菜单、复选框或日期选择器。本页说明如何使用这些通用组件。
*复选框(checkbox)
一个简单的复选框组件,旁边有一个标签
代码位置:
@web/core/checkbox/checkbox

描述
这是一个简单的复选框组件,旁边有一个标签。复选框链接到标签:只要单击标签,复选框就会切换。

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

其中:value如果为真,则选中复选框,否则不选中
disabled如果为 true,则禁用复选框,否则启用
*下拉列表(dropdown)
代码位置:
@web/core/dropdown/dropdown和@web/core/dropdown/dropdown_item

drowdown包含两个组件:一个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 t-on-dropdown-item-selected="selectItem1">Menu Item 1</DropdownItem><DropdownItem t-on-dropdown-item-selected="selectItem2">Menu Item 2</DropdownItem>
</Dropdown>

属性:

一个<Dropdown/>组件的组成: 首先是<div class="dropdown"/> ,然后是一个 <button class="dropdown-toggle"/> 最后是MENU (<div class="dropdown-menu"/>). button决定下拉菜单项是否显示.

下拉列表Dropdown 类型 描述
startOpen 布尔值 初始下拉菜单打开状态(默认为false)
menuClass 字符 应用于下拉菜单的附加 CSS 类<div class="dropdown-menu"/>
togglerClass 字符 应用于切换器的附加 CSS 类<button class="dropdown-toggle"/>
hotkey 字符 通过键盘切换打开的热键
beforeOpen function 在打开之前执行逻辑。可能是异步的。
manualOnly 布尔值 如果为 true,则仅在单击按钮时切换下拉列表(默认为false)
title 字符 标题属性内容(默认值:无)
position 字符 定义菜单打开位置。自动应用 RTL 方向。应该是一个有效的usePosition钩子位置。(默认bottom-start:)
toggler "parent"或者undefined 当设置"parent"为不呈现时(此j时插槽(slot)被忽略)并且切换功能由父节点处理。(默认:)<button class="dropdown-toggle"/>togglerundefined

一个<DropdownItem/>就是一个<span class="dropdown-item"/>标记。当一个<DropdownItem/>被选择,它会触发一个自定义的事件dropdown-item-selected ,为了响应此事件,需要定义一个事件监听。

| 下拉列表项

DropdownItem 类型 描述
payload 对象 将事件挂载到 dropdown-item-selected上去
parentClosingMode none/closest/all 当某个ITEM被选中,控制哪个父对象将被关闭,分为无,本级的父对象和所有
hotkey 字符 用于选择项目的可选热键
href 字符 如果提供这个关键字, DropdownItem 将变成 来替代 . (默认:fii 未提供)
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>

要正确使用组件,需要设置两个 OWL 插槽:

toggler slot:它包含下拉列表的菜单切换元素,并在下拉列表中呈现button(除非toggler设置为parent).
default slot:它包含下拉菜单本身的元素,并被渲染在 <div class="dropdown-menu"/>里面. 虽然不是强制性的,但通常插槽至少有一个。

当多个下拉菜单在 DOM 中共享相同的父元素时,它们被视为组的一部分,并将相互通知它们的状态更改。这意味着当其中一个下拉菜单打开时,其他下拉菜单将在鼠标悬停时自动打开,而无需单击。
示例:同组下拉列表
当单击一个下拉toggle(File、Edit或About)时,其他的将在悬停时自行打开。

<div t-on-dropdown-item-selected="onItemSelected"><Dropdown><t t-set-slot="toggler">File</t><DropdownItem payload="'file-open'">Open</DropdownItem><DropdownItem payload="'file-new-document'">New Document</DropdownItem><DropdownItem payload="'file-new-spreadsheet'">New Spreadsheet</DropdownItem></Dropdown><Dropdown><t t-set-slot="toggler">Edit</t><DropdownItem payload="'edit-undo'">Undo</DropdownItem><DropdownItem payload="'edit-redo'">Redo</DropdownItem><DropdownItem payload="'edit-find'">Search</DropdownItem></Dropdown><Dropdown><t t-set-slot="toggler">About</t><DropdownItem payload="'about-help'">Help</DropdownItem><DropdownItem payload="'about-update'">Check update</DropdownItem></Dropdown>
</div>

示例:多级下拉菜单(带有t-call)
这个例子展示了如何制作一个File下拉菜单,其中包含新建和保存两个子菜单及其中的子元素.

<t t-name="addon.Dropdown.File" owl="1"><Dropdown t-on-dropdown-item-selected="onItemSelected"><t t-set-slot="toggler">File</t><DropdownItem payload="'file-open'">Open</DropdownItem><t t-call="addon.Dropdown.File.New"/><DropdownItem payload="'file-save'">Save</DropdownItem><t t-call="addon.Dropdown.File.Save.As"/></Dropdown>
</t><t t-name="addon.Dropdown.File.New" owl="1"><Dropdown><t t-set-slot="toggler">New</t><DropdownItem payload="'file-new-document'">Document</DropdownItem><DropdownItem payload="'file-new-spreadsheet'">Spreadsheet</DropdownItem></Dropdown>
</t><t t-name="addon.Dropdown.File.Save.As" owl="1"><Dropdown><t t-set-slot="toggler">Save as...</t><DropdownItem payload="'file-save-as-csv'">CSV</DropdownItem><DropdownItem payload="'file-save-as-pdf'">PDF</DropdownItem></Dropdown>
</t>

示例:多级下拉菜单(嵌套)

<Dropdown t-on-dropdown-item-selected="onItemSelected"><t t-set-slot="toggler">File</t><DropdownItem payload="'file-open'">Open</DropdownItem><Dropdown><t t-set-slot="toggler">New</t><DropdownItem payload="'file-new-document'">Document</DropdownItem><DropdownItem payload="'file-new-spreadsheet'">Spreadsheet</DropdownItem></Dropdown><DropdownItem payload="'file-save'">Save</DropdownItem><Dropdown><t t-set-slot="toggler">Save as...</t><DropdownItem payload="'file-save-as-csv'">CSV</DropdownItem><DropdownItem payload="'file-save-as-pdf'">PDF</DropdownItem></Dropdown>
</Dropdown>

猫头鹰组件
Odoo Javascript 框架使用称为 Owl 的自定义组件框架。它是一个声明式组件系统,受到 Vue 和 React 的粗略启发。组件使用QWeb 模板定义,并添加了一些 Owl 特定指令。Owl官方 文档 包含完整的参考资料和教程。

重要的

Although the code can be found in the web module, it is maintained from a separate GitHub repository. Any modification to Owl should therefore be made through a pull request on https://github.com/odoo/owl.

Note

Currently, all Odoo versions (starting in version 14) share the same Owl version.

Using Owl components
The Owl documentation already documents in detail the Owl framework, so this page will only provide Odoo specific information. But first, let us see how we can make a simple component in 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>;
This example shows that Owl is available as a library in the global namespace as owl: it can simply be used like most libraries in Odoo. Note that we defined here the template as a static property, but without using the static keyword, which is not available in some browsers (Odoo javascript code should be Ecmascript 2019 compliant).

We define here the template in the javascript code, with the help of the xml helper. However, it is only useful to get started. In practice, templates in Odoo should be defined in an xml file, so they can be translated. In that case, the component should only define the template name.

In practice, most components should define 2 or 3 files, located at the same place: a javascript file (my_component.js), a template file (my_component.xml) and optionally a scss (or css) file (my_component.scss). These files should then be added to some assets bundle. The web framework will take care of loading the javascript/css files, and loading the templates into Owl.

Here is how the component above should be defined:

const { useState } = owl.hooks;

class MyComponent extends Component {

}
MyComponent.template = ‘myaddon.MyComponent’;
And the template is now located in the corresponding xml file:

<?xml version="1.0" encoding="UTF-8" ?> Odoo code is not yet completely made in Owl, so it needs a way to tell the difference between Owl templates (new code) and old templates (for components). To do that in a backward-compatible way, all new templates should be defined with the owl attribute set to 1.

Note

Do not forget to set owl=“1” in your Owl templates!

Note

Template names should follow the convention addon_name.ComponentName.

See also

Owl Repository

Best practices
First of all, components are classes, so they have a constructor. But constructors are special methods in javascript that are not overridable in any way. Since this is an occasionally useful pattern in Odoo, we need to make sure that no component in Odoo directly uses the constructor method. Instead, components should use the setup method:

// correct:
class MyComponent extends Component {
setup() {
// initialize component here
}
}

// incorrect. Do not do that!
class IncorrectComponent extends Component {
constructor(parent, props) {
// initialize component here
}
}
Another good practice is to use a consistent convention for template names: addon_name.ComponentName. This prevents name collision between odoo addons.

Reference List
The Odoo web client is built with Owl components. To make it easier, the Odoo javascript framework provides a suite of generic components that can be reused in some common situations, such as dropdowns, checkboxes or datepickers. This page explains how to use these generic components.

Technical Name

Short Description

CheckBox

a simple checkbox component with a label next to it

Dropdown

full-featured dropdown

CheckBox
Location
@web/core/checkbox/checkbox

Description
This is a simple checkbox component with a label next to it. The checkbox is linked to the label: the checkbox is toggled whenever the label is clicked.

Some Text Props Name

Type

Description

value

boolean

if true, the checkbox is checked, otherwise it is unchecked

disabled

boolean

if true, the checkbox is disabled, otherwise it is enabled

Dropdown
Location
@web/core/dropdown/dropdown and @web/core/dropdown/dropdown_item

Description
Dropdowns are surprisingly complicated components. They need to provide many features such as:

Toggle the item list on click

Direct siblings dropdowns: when one is open, toggle others on hover

Close on outside click

Optionally close the item list when an item is selected

Emit an event to inform which list item is clicked

Support sub dropdowns, up to any level

SIY: style it yourself

Configurable hotkey to open/close a dropdown or select a dropdown item

Keyboard navigation (arrows, tab, shift+tab, home, end, enter and escape)

Reposition itself whenever the page scrolls or is resized

Smartly chose the direction it should open (right-to-left direction is automatically handled).

To solve these issues once and for all, the Odoo framework provides a set of two components: a Dropdown component (the actual dropdown), and DropdownItem, for each element in the item list.

Click me to toggle the dropdown menu ! Menu Item 1 Menu Item 2 Props A component is simply a

having a next to menu div (

). The button is responsible for the menu being present in the DOM or not.

Dropdown

Type

Description

startOpen

boolean

initial dropdown open state (defaults to false)

menuClass

string

additional css class applied to the dropdown menu

togglerClass

string

additional css class applied to the toggler

hotkey

string

hotkey to toggle the opening through keyboard

beforeOpen

function

hook to execute logic just before opening. May be asynchronous.

manualOnly

boolean

if true, only toggle the dropdown when the button is clicked on (defaults to false)

title

string

title attribute content for the (default: none)

position

string

defines the desired menu opening position. RTL direction is automatically applied. Should be a valid usePosition hook position. (default: bottom-start)

toggler

“parent” or undefined

when set to “parent” the is not rendered (thus toggler slot is ignored) and the toggling feature is handled by the parent node (e.g. use case: pivot cells). (default: undefined)

A is simply a span (). When a is selected, it emits a custom dropdown-item-selected event containing its payload. (see OWL Business Events). So, to react to such an event, one needs to define an event listener on the dropdown-item-selected event.

DropdownItem

Type

Description

payload

Object

payload that will be added to the dropdown-item-selected event (default to null)

parentClosingMode

none | closest | all

when the item is selected, control which parent dropdown will get closed: none, closest or all (default = all)

hotkey

string

optional hotkey to select the item

href

string

如果提供 DropdownItem 将变为 a而不是. (默认:未提供)

title

细绳

可选的标题属性,将传递给 DropdownItem 的根节点。(默认:未提供)

技术说明
渲染的 DOM 结构如下:

Click me !

Menu Item 1 Menu Item 2

要正确使用组件,您需要填充两个 OWL 插槽:

togglerslot:它包含下拉列表的切换器元素,并在下拉列表中呈现button(除非toggler道具设置为parent),

defaultslot:它包含下拉菜单本身的元素,并在. 虽然不是强制性的,但通常在 插槽内至少有一个。

DropdownItemmenu

当多个下拉菜单在 DOM 中共享相同的父元素时,它们被视为组的一部分,并将相互通知它们的状态更改。这意味着当其中一个下拉菜单打开时,其他下拉菜单将在鼠标悬停时自动打开,而无需单击。

示例:直接兄弟姐妹下拉列表
当单击一个下拉切换器(File、Edit或About)时,其他的将在悬停时自行打开。

File Open New Document New Spreadsheet Edit Undo Redo Search About Help Check update

示例:多级下拉菜单(带有t-call) 这个例子展示了如何制作一个File下拉菜单,其中包含New和子元素的子菜单。Save as... File Open Save New Document Spreadsheet Save as... CSV PDF 示例:多级下拉菜单(嵌套) File Open New Document Spreadsheet Save Save as... CSV PDF 示例:递归多级下拉菜单 在这个例子中,我们递归调用一个模板来显示一个树状结构。

<t t-name="addon.MainTemplate" owl="1"><div t-on-dropdown-item-selected="onItemSelected"><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" owl="1"><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 payload="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>

odoo owl解释相关推荐

  1. 手把手带你学会Odoo OWL组件开发(5):浅析OWL原理

    [本系列内容直达:] 手把手带你学习Odoo OWL组件开发(1):认识 OWL 手把手带你学会Odoo OWL组件开发(2):OWL的使用 手把手带你学会Odoo OWL组件开发(3):核心内容指南 ...

  2. 手把手带你学会Odoo OWL组件开发(4):OWL组件

    [本系列内容直达:] 手把手带你学习Odoo OWL组件开发(1):认识 OWL 手把手带你学会Odoo OWL组件开发(2):OWL的使用 手把手带你学会Odoo OWL组件开发(3):核心内容指南 ...

  3. Odoo owl 20220401 学习列表

    Here is a list of everything exported by the Owl library: odoo owl 20220401学习列表 目录 Odoo owl 20220401 ...

  4. 手把手带你学会Odoo OWL组件开发(2):OWL的使用

    [本系列内容直达:] [手把手带你学习Odoo OWL组件开发(1):认识 OWL] [手把手带你学会Odoo OWL组件开发(2):OWL的使用] [手把手带你学会Odoo OWL组件开发(3):核 ...

  5. 【ODOO OWL】第一课 OWL项目概况

    目录 OWL项目概况 OWL的主要特性 ODOO为什么需要OWL 核心架构不易变更 技术控制 开发友好 总结 简单的示例及说明 设计原则 OWL项目概况 OWL,即Odoo Web Libary.是O ...

  6. 【ODOO OWL】基础 Owl 的 mount 挂载应用程序

    挂载一个Owl应用程序是通过使用mount方法来完成的.如果您使用的是 iife 版本,您可以通过`owl.mount`使用它,如果您使用的是模块系统,您可以直接从 `owl` 导入它. mount方 ...

  7. 【ODOO OWL】工具 Owl 的 Utils

    Utils Owl导出了一些有用的实用程序功能,以帮助解决常见问题.这些功能在 owl.utils 命名空间中都可用. whenReady:在DOM就绪时执行代码 loadJS:加载脚本文件 load ...

  8. ODOO--OWL简介

    1.什么是OWL OWL是 Odoo 创建的前端开发框架.这是他们在最新版本的 Odoo(版本 14)中引入的一个框架,以使前端代码更好一些.如果您熟悉其他前端框架,如 React.Vue.Angul ...

  9. odoo12:自动生成序列号方法

    为了我们插入数据的效率,我们会想到自动生成序列号.那么怎么生成预想的序列号呢?下面我们就来看看. 1.data/data.xml <?xml version="1.0" en ...

最新文章

  1. 【转载】利用Matlab制作钟表
  2. linux禁止线程网络,linux – 如何在gdb中禁用新线程/线程退出的消息?
  3. boost::geometry::detail::overlay::get_ring用法的测试程序
  4. 微软将降低Visual Studio对操作系统的影响
  5. Python进阶-函数默认参数,特别是参数传递为空列表
  6. CVPR2019 oral 目标跟踪算法之SiamRPN++
  7. 点赞功能设计,网上的,留个底
  8. EOS cleos --skip-transaction-signatures 跳过签名
  9. 怎么把两个pdf合并成一个?
  10. 阿里云移动推送学习笔记
  11. 记录阿里云增加二级域名步骤[同三级]
  12. WebApp最佳实践用户体验篇:针对多种屏幕尺寸合理设计
  13. 固定表头和第一列、内容可滚动的table表格
  14. 2020机修钳工(中级)考试及机修钳工(中级)复审模拟考试
  15. 基于elementUI封装了基础表单组件
  16. 网络安全入门:什么是防火墙,防火墙有哪些功能
  17. 嵌入式linux启动信息完全注释
  18. 国内医院临床自闭症病例分享:大脑自闭了,为什么是肠道的锅?
  19. 金融课第二次测试笔记
  20. C语言笔试题(嵌入式软件开发)

热门文章

  1. 『生于八十』[郁郁寡欢]住在隔壁的刚毕业的大学生80小夫妻(我看完之后沉默...(转载)...
  2. UI设计是什么?UI设计师的工作内容有哪些?了解一下
  3. OpenCV 下载驿站(百度云盘下载,同步更新)
  4. java通过Solr的Suggest实现提示词
  5. ASP.NET实现登录页面
  6. 聚美出空气净化器 陈欧再为自己代言
  7. python中的进制转换以及浮点数二进制转换
  8. 预产期计算器在线计算生男生女计算机,预产期计算器生男生女方法(附预测表)...
  9. 程序员:你敢找我做这事,我就敢拉黑你!
  10. 2019 CCPC秦皇岛 K.MUV LUV UNLIMITED(博弈)