JavaScript 参考

本文档介绍了 Odoo Javascript 框架。就代码行而言,该框架并不是一个大型应用程序,但它非常通用,因为它基本上是一台将声明性接口描述转换为实时应用程序的机器,能够与数据库中的每个模型和记录进行交互。 甚至可以使用Web客户端来修改Web客户端的界面。

概述

Javascript 框架旨在处理三个主要用例:

  • 网络客户端:这是私有网络应用程序,可以在其中查看和编辑业务数据。这是一个单页面应用程序(页面永远不会重新加载,仅在需要时从服务器获取新数据)

  • 网站:这是 Odoo 的公共部分。 它允许身份不明的用户作为客户端浏览某些内容、购物或执行许多操作。这是一个经典的网站:带有控制器的各种路由和一些 javascript 使其工作。

  • 销售点:这是销售点的界面。它是一个专门的单页应用程序。

一些 JavaScript 代码对于这三个用例来说是通用的,并且捆绑在一起(请参阅下面的资产部分)。 本文档将主要关注 Web 客户端的架构。

网页客户端

单页应用程序

Web 客户端是一个单页应用程序:它不会在用户每次执行操作时向服务器请求完整页面,而是仅加载该操作更新用户界面 (UI) 所需的内容。在执行此操作时,它还负责更新 URL 中的信息,因此,在大多数情况下,刷新页面或关闭浏览器并再次打开它会显示相同的内容。

Web客户端JS代码概述

在这里,我们快速概述了 web 插件中的 Web 客户端代码。将相对于 web/static/src 描述路径。以下描述故意不详尽;目标只是让读者鸟瞰该架构。

  • module_loader.js:这是定义 Odoo javascript 模块系统的文件。 它需要在任何其他 JS 模块之前加载。

  • core/:此文件夹包含构成 JavaScript 框架最低级别的代码,可在 Web 客户端以及网站、门户和销售点应用程序中使用。

  • weblient/:此文件夹包含特定于 Web 客户端且不能在网站或销售点中使用的文件,例如操作管理器和操作服务。

  • webclient/webclient.js:这是正确的网络客户端组件。它主要是操作容器和导航栏的包装器,并执行启动应用程序时所需的一些操作,例如加载 url 的状态。

  • webclient/actions/:此文件夹包含负责显示和在操作之间切换的代码。

  • views/:此文件夹包含视图基础结构的代码以及大多数视图(某些类型的视图是由其他插件添加的)。

  • views/fields/:包含各个字段组件的定义,以及多个字段使用的一些实用程序。

  • search/ 所有这些文件定义了搜索视图(它不是 Web 客户端角度的视图,仅是服务器角度的视图)

如果文件未加载/更新该怎么办

文件无法正确加载的原因有很多。 您可以尝试以下一些方法来解决该问题:

  • 确保您保存了文件;我们中最优秀的人都会忘记这样做。

  • 查看控制台(在开发工具中,通常使用 F12 打开)并检查是否有错误。

  • 尝试在文件开头添加 console.log() ,以便您可以查看文件是否已加载。如果未加载,则可能不在正确的资源包中,或者资源包可能不是最新的。

  • 根据您的设置,文件修改后服务器可能不会重新生成资源包;有几个选项可以解决这个问题:

    • 重新启动服务器将强制它在下次请求时检查资源包是否是最新的

    • 在调试模式下,调试菜单(导航栏中的:icon:`fa-bug`按钮)中有一个选项可以强制服务器动态重新生成资源包而无需重新启动。

    • 使用 --dev=xml 选项启动服务器将强制服务器在每次请求时检查资源包是否是最新的。我们建议您在积极开发时使用此选项,但不要在生产中使用。

  • 确保更改代码后刷新页面。 Odoo 目前没有任何热模块重载机制。

加载Javascript代码

大型应用程序通常被分成较小的文件,需要将它们连接在一起。 某些文件可能需要使用另一个文件中定义的代码。在文件之间共享代码有两种方法:

  • 使用全局范围(window 对象)来读取/写入对某些对象或函数的引用,

  • 使用模块系统,该系统将为每个模块提供导出或导入值的方法,并确保它们以正确的顺序加载。

虽然可以在全球范围内工作,但这存在许多问题:

  • 很难确保实现细节不被暴露:全局作用域中的函数声明可供所有其他代码访问。

  • 由于存在单一命名空间,因此存在命名冲突的巨大可能性。

  • 依赖关系是隐式的:如果一段代码依赖于另一段代码,那么它们的加载顺序很重要,但很难保证。

使用模块系统有助于解决这些问题:因为模块指定了它们的依赖项,所以模块系统可以按正确的顺序加载它们,或者在依赖项丢失或循环时发出错误。模块还形成自己的命名空间,并且可以选择导出什么,从而防止暴露实现细节和命名冲突。

虽然我们可以直接使用 ECMAScript (ES) 模块,但这种方法有很多缺点:每个 ES 模块都需要网络往返,当您有数百个文件时,这会变得非常慢,并且 Odoo 中的许多文件需要存在,尽管没有被任何东西导入,因为它们只是添加框架将使用的代码,而不是相反。

正因为如此,Odoo 有一个资产捆绑系统。在这些包中,JavaScript 文件是 ES 模块,顶部有一个特殊的注释。这些模块将捆绑在一起并转译为可供我们的模块加载器使用。虽然您可以编写不使用此模块系统的代码,但通常不建议这样做。

(参见:ref:frontend/modules/native_js

修补类

虽然我们尽力提供不需要它的扩展点,但有时有必要“就地”修改现有类的行为。目标是拥有一种更改类和所有未来/当前实例的机制。这是通过使用 patch 实用函数来完成的:

import { Hamster } from "@web/core/hamster"
import { patch } from "@web/core/utils/patch";

patch(Hamster.prototype, {
    sleep() {
        super.sleep(...arguments);
        console.log("zzzz");
    },
});

修补方法时,您需要修补类的原型,但如果您想修补类的静态属性,则需要修补类本身。

修补是一项危险的操作,应该小心执行,因为它会修改类的所有实例,即使它们已经被创建。为了避免出现奇怪的问题,应尽快在模块的顶层应用补丁。如果类已经实例化,则在运行时修补类可能会导致极其难以调试的问题。

登记处

Odoo 生态系统中的一个常见需求是从外部扩展/更改基本系统的行为(通过安装应用程序,即不同的模块)。 例如,可能需要在某些视图中添加新的字段小部件。在这种情况下以及许多其他情况下,通常的过程是创建所需的组件,然后将其添加到注册表(注册步骤),以使 Web 客户端的其余部分知道它的存在。

系统中有一些可用的注册表。框架使用的注册表是主注册表上的类别,可以从 @web/core/registry 导入

现场登记处

字段注册表包含 Web 客户端已知的所有字段小部件。每当视图(通常是表单或列表/看板)需要字段小部件时,它就会在此处查看。典型的用例如下所示:

import { registry } from "@web/core/registry";
class PadField extends Component { ... }

registry.category("fields").add("pad", {
  component: PadField,
  supportedTypes: ["char"],
  // ...
});
查看注册表

该注册表包含 Web 客户端已知的所有 JS 视图。

行动登记处

我们在此注册表中跟踪所有客户端操作。 这是操作管理器在需要创建客户端操作时查找的位置。客户端操作可以是一个函数 - 该函数将在调用该操作时被调用,并且返回的值将在需要时作为后续操作执行 - 或者是一个在执行该操作时将显示的 Owl 组件。

服务

在 Web 客户端中,有一些问题无法由单个组件处理,因为问题是横向的、涉及许多组件,或者只要应用程序处于活动状态就需要维护某些状态。

服务是这些问题的解决方案:它们在应用程序启动期间创建,可通过钩子 useService 供组件使用,并在应用程序的整个生命周期中保持活动状态。

例如,我们有 orm 服务,其工作是允许与服务器上的业务对象进行交互。

下面是一个关于如何实现 orm 服务的简化示例:

import { registry } from "@web/core/registry";
export const OrmService = {
    start() {
        return {
            read(...) { ... },
            write(...) { ... },
            unlink(...) { ... },
            ...
        }
    },
};
registry.category("services").add("orm", OrmService);

使用服务

服务在环境中可用,但通常应通过 useService 挂钩使用,这可以防止在组件被销毁后调用服务上的方法,并且如果组件在调用期间被销毁,则可以防止在方法调用后执行进一步的代码。

class SomeComponent extends Component {
    setup() {
        this.orm = useService("orm");
    }
    // ...
    getActivityModelViewID(model) {
        return this.orm.call(model, "get_activity_view_id", this.params);
    }
}

与服务器对话

使用 Odoo 时通常有两种用例:一种可能需要调用 (python) 模型上的方法(这通过控制器 /web/dataset/call_kw),或者可能需要直接调用控制器(在某些路由上可用)。

  • 在 python 模型上调用方法是通过 orm 服务完成的:

    return this.orm.call("some.model", "some_method", [some, args]);
    
  • 直接调用控制器是通过rpc服务完成的:

    return this.rpc("/some/route/", {
        some: param,
    });
    

注解

rpc 服务并不真正执行通常理解的远程过程调用 (RPC),但由于历史原因,在 Odoo 中,我们通常将 JavaScript 中执行的任何网络请求称为 RPC。正如上一段所强调的,如果您想调用模型上的方法,您应该使用 orm 服务。

通知

Odoo 框架有一种向用户传达各种信息的标准方式:通知,显示在用户界面的右上角。通知类型遵循引导程序 toast:

  • info:用于显示一些信息反馈,作为不会失败的操作的结果。

  • 成功:用户执行了有时会失败的操作,但最终没有执行。

  • 警告:用户执行了只能部分完成的操作。如果出现错误但不是由用户直接造成的,或者不是特别可操作的,也很有用。

  • 成功:用户尝试执行操作但无法完成。

通知还可以用于向用户询问问题,而不会干扰他们的工作流程:例如通过 VOIP 接到的电话:可以显示粘性通知,其中有两个按钮*接受*或*拒绝*。

显示通知

Odoo 中有两种显示通知的方式:

  • notification 服务允许组件通过调用 add 方法来显示来自 JS 代码的通知。

  • display_notification 客户端操作允许触发来自 python 的通知的显示(例如,在用户单击对象类型的按钮时调用的方法中)。此客户端操作使用通知服务。

通知有几个*选项*:

  • 标题:字符串,可选。这将作为标题显示在顶部。

  • 消息:字符串,可选。通知的内容。可以是显示格式化文本的标记对象。

  • sticky:布尔值,可选(默认 false)。如果为 true,则通知将一直保留,直到用户将其关闭。 否则,通知将在短暂延迟后自动关闭。

  • 类型:字符串,可选(默认“警告”)。确定通知的样式。可能的值:“信息”、“成功”、“警告”、“危险”

  • className:字符串,可选。 这是一个 CSS 类名称,将自动添加到通知中。尽管不鼓励使用它,但这对于样式目的可能很有用。

下面是一些关于如何在 JS 中显示通知的示例:

// note that we call _t on the text to make sure it is properly translated.
this.notification.add({
    title: _t("Success"),
    message: _t("Your signature request has been sent.")
});
this.notification.add({
    title: _t("Error"),
    message: _t("Filter name is required."),
    type: "danger",
});

在 Python 中:

# note that we call _(string) on the text to make sure it is properly translated.
def show_notification(self):
    return {
        'type': 'ir.actions.client',
        'tag': 'display_notification',
        'params': {
            'title': _('Success'),
            'message': _('Your signature request has been sent.'),
            'sticky': False,
        }
    }

系统托盘

系统托盘是界面中导航栏的右侧部分,Web 客户端在其中显示一些小部件,例如消息传递菜单。

当导航栏创建系统托盘时,它将查找所有注册的系统托盘项目并显示它们。

目前没有针对系统托盘项的特定 API。 它们是 Owl 组件,可以像其他组件一样与环境进行通信,例如通过与服务交互。

添加新的系统托盘项

可以通过将项目添加到“systray”注册表来将其添加到系统托盘中:

import { registry } from "@web/core/registry"
class MySystrayComponent extends Component {
    ...
}
registry.category("systray").add("MySystrayComponent", MySystrayComponent, { sequence: 1 });

这些项目根据其在系统托盘注册表中的顺序在系统托盘中排序。

翻译管理

有些翻译是在服务器端进行的(基本上所有文本字符串都是由服务器渲染或处理的),但静态文件中有字符串需要翻译。目前它的工作方式如下:

  • 每个可翻译字符串都标有特殊函数 _t

  • 服务器使用这些字符串来生成正确的 PO 文件

  • 每当加载 Web 客户端时,它都会调用路由 /web/webclient/translations,该路由返回所有可翻译术语的列表

  • 在运行时,每当调用函数 _t 时,它都会在此列表中查找翻译,如果没有找到,则返回它或原始字符串。

请注意,从服务器的角度来看,文档 翻译模块 中对翻译进行了更详细的解释。

import { _t } from "@web/core/l10n/translation";

class SomeComponent extends Component {
    static exampleString = _t("this should be translated");
    ...
    someMethod() {
        const str = _t("some text");
    }
}

请注意,使用翻译函数需要小心:作为参数给出的字符串不能是动态的,因为它是从代码中静态提取以生成 PO 文件并用作要翻译的术语的标识符。如果需要在字符串中注入一些动态内容,_t 支持占位符:

import { _t } from "@web/core/l10n/translation";
const str = _t("Hello %s, you have %s unread messages.", user.name, unreadCount);

注意字符串本身是如何固定的。这允许翻译函数*在*使用它进行插值之前检索翻译后的字符串。

会议

Web 客户端需要来自 python 的一些信息才能正常运行。为了避免在 JavaScript 中进行网络请求而与服务器进行额外的往返,这些信息直接在页面中序列化,并且可以通过 @web/session 模块在 JS 中访问。

向会话添加信息

当加载 /web 路由时,服务器会将此信息注入到脚本标记中。该信息是通过调用模型`ir.http`的方法`session_info`来获取的。您可以重写此方法以将信息添加到返回的字典中。

from odoo import models
from odoo.http import request

class IrHttp(models.AbstractModel):
    _inherit = ['ir.http']

    def session_info(self):
        result = super(IrHttp, self).session_info()
        result['some_key'] = get_some_value_from_db()
        return result

现在,可以通过在会话中读取 javascript 来获取该值:

import { session } from "@web/session"
const myValue = session.some_key;
...

请注意,此机制旨在减少 Web 客户端准备就绪所需的通信量。 它仅适用于计算成本较低的数据(缓慢的 session_info 调用将延迟每个人的 Web 客户端的加载),以及初始化过程早期所需的数据。

意见

“视图”一词有不止一个含义。本节是关于视图的 javascript 代码的设计,而不是 arch 或其他任何内容的结构。

虽然视图只是 owl 组件,但内置视图通常具有相同的结构:一个名为“SomethingController”的组件,它是视图的根。该组件创建某个“模型”(负责管理数据的对象)的实例,并具有一个称为“渲染器”的子组件,用于处理显示逻辑。

领域

Web 客户端体验的很大一部分是编辑和创建数据。大部分工作是在字段小部件的帮助下完成的,这些小部件知道字段类型以及如何显示和编辑值的具体细节。

装饰

与列表视图一样,字段小部件对装饰有简单的支持。装饰的目标是有一种简单的方法来根据记录的当前状态指定文本颜色。 例如:

<field name="state" decoration-danger="amount &lt; 10000"/>

有效的装饰名称是:

  • decoration-bf

  • decoration-it

  • decoration-danger

  • decoration-info

  • decoration-muted

  • decoration-primary

  • decoration-success

  • decoration-warning

每个装饰 decoration-X 都会映射到一个 css 类 text-X,这是一个标准的 bootstrap css 类(text-ittext-bf 除外,它们由 odoo 处理,分别对应斜体和粗体)。 请注意,装饰属性的值应该是有效的 python 表达式,它将使用记录作为评估上下文进行评估。

非关系字段

我们在这里记录了默认情况下可用的所有非关系字段,没有特定的顺序。

整数 (integer)

这是 integer 类型字段的默认字段类型。

  • 支持的字段类型:integer

选项:

  • type:设置输入类型(默认为`”text”,可在”number”`上设置)

    在编辑模式下,该字段将呈现为在 "number" 上设置的 HTML 属性类型的输入(因此用户可以受益于本机支持,尤其是在移动设备上)。在这种情况下,将禁用默认格式以避免不兼容。

    <field name="int_value" options="{'type': 'number'}" />
    
  • step:设置用户点击按钮时的上下数值(仅适用于数字类型的输入,默认为`1`)

    <field name="int_value" options="{'type': 'number', 'step': 100}" />
    
  • format:数字是否应该格式化。 (默认为 true

    默认情况下,数字根据区域设置参数进行格式化。此选项将阻止字段值被格式化。

    <field name="int_value" options='{"format": false}' />
    
浮动 (float)

这是 float 类型字段的默认字段类型。

  • 支持的字段类型:float

属性:

  • digits:显示精度

    <field name="factor" digits="[42,5]" />
    

选项:

  • type:设置输入类型(默认为`”text”,可在”number”`上设置)

    在编辑模式下,该字段将呈现为在 "number" 上设置的 HTML 属性类型的输入(因此用户可以受益于本机支持,尤其是在移动设备上)。在这种情况下,将禁用默认格式以避免不兼容。

    <field name="float_value" options="{'type': 'number'}" />
    
  • step:设置用户点击按钮时的上下数值(仅适用于数字类型的输入,默认为`1`)

    <field name="float_value" options="{'type': 'number', 'step': 0.1}" />
    
  • format:数字是否应该格式化。 (默认为 true

    默认情况下,数字根据区域设置参数进行格式化。此选项将阻止字段值被格式化。

    <field name="float_value" options="{'format': false}" />
    
  • min_display_digits:要显示的最小小数位数。

    例如,如果设置为 3 并且不提供小数精度:1.2 变为 "1.200"1.123 变为 "1.123"1.1234 变为 "1.1234"

    <field name="float_value" options="{'min_display_digits': 3}" />
    
  • hide_trailing_zeros:隐藏最后一个非零数字右侧的零,例如`1.20` 变为 1.2`(默认为 `false)。

    <field name="float_value" options="{'hide_trailing_zeros': true}" />
    
时间 (float_time)

该小部件的目标是正确显示表示时间间隔(以小时为单位)的浮点值。 因此,例如,0.5 应格式化为 0:30,或 4.75 对应于 4:45

  • 支持的字段类型:float

浮动系数 (float_factor)

该小部件旨在正确显示使用其选项中给出的因子转换的浮点值。因此,例如,数据库中保存的值为 0.5,因子为 3,小部件值应格式化为 1.5

  • 支持的字段类型:float

浮动切换 (float_toggle)

该小部件的目标是用包含一系列可能值(在选项中给出)的按钮替换输入字段。每次单击都允许用户在范围内循环。此处的目的是将字段值限制为预定义的选择。此外,该小部件支持因子转换,如 float_factor 小部件(范围值应该是转换的结果)。

  • 支持的字段类型:float

<field name="days_to_close" widget="float_toggle" options="{'factor': 2, 'range': [0, 4, 8]}" />
布尔值 (boolean)

这是 boolean 类型字段的默认字段类型。

  • 支持的字段类型:boolean

字符 (char)

这是 char 类型字段的默认字段类型。

  • 支持的字段类型:char

日期 (date)

这是 date 类型字段的默认字段类型。它由一个文本框和一个日期选择器组成。该字段将以可读格式显示日期,如下所示:Dec 19, 1997。如果是当前年份,年份将被隐藏。编辑字段时,将显示数字格式。该格式对应于当前语言中的一组格式。

  • 支持的字段类型:date

选项:

  • min_date / max_date:设置接受值的限制日期。默认情况下,最早接受的日期是 1000-01-01,最晚接受的日期是 9999-12-31。接受的值为 SQL 格式的日期 (yyyy-MM-dd HH:mm:ss) 或 "today"

    <field name="datefield" options="{'min_date': 'today', 'max_date': '2023-12-31'}" />
    
  • warn_future:如果该值是将来的值(基于今天),则显示警告。

    <field name="datefield" options="{'warn_future': true}" />
    
  • numeric:设置为 true 时,以当前语言设置的格式显示日期。 (默认值:false)。

    <field name="datefield" options="{'numeric': true}" />
    
日期和时间 (datetime)

这是 datetime 类型字段的默认字段类型。这些值始终位于客户端的时区。显示的格式与日期字段具有相同的行为,请参阅 Date Field 说明。可读格式如下:Dec 19, 1997, 10:45 AM

  • 支持的字段类型:datetime

选项:

  • 请参阅 Date Field 选项

  • rounding:用于在时间选择器中生成可用分钟的增量。这不会影响实际值,只会影响选择下拉列表中可用选项的数量(默认值:5)。

    <field name="datetimefield" options="{'rounding': 10}" />
    
  • show_seconds:设置为 true 时,显示日期时间字段中的秒数。该字段仍接受日期时间值,但秒数将显示在 UI 中(默认值:false)。

    <field name="datetimefield" widget="datetime" options="{'show_seconds': true}" />
    
  • show_time:当设置为 false 时,它​​会隐藏日期时间字段中的时间部分。该字段仍将接受日期时间值,但时间部分将隐藏在 UI 中(默认值:true)。

    <field name="datetimefield" widget="datetime" options="{'show_time': false}" />
    
  • show_date:当设置为 false 时,它​​会隐藏日期时间字段中的日期部分。该字段仍将接受日期时间值,但日期部分将隐藏在 UI 中(默认值:true)。

    <field name="datetimefield" widget="datetime" options="{'show_date': false}" />
    
日期范围 (daterange)

该小部件允许用户从单个选择器中选择开始和结束日期。

  • 支持的字段类型:datedatetime

选项:

  • 请参阅 Date FieldDate & Time Field 选项

  • start_date_field:用于获取/设置日期范围的起始值的字段(不能与 end_date_field 一起使用)。

    <field name="end_date" widget="daterange" options="{'start_date_field': 'start_date'}" />
    
  • end_date_field:用于获取/设置日期范围的结束值的字段(不能与 start_date_field 一起使用)。

    <field name="start_date" widget="daterange" options="{'end_date_field': 'end_date'}" />
    
剩余天数 (remaining_days)

该小部件可用于日期和日期时间字段。在只读状态下,它显示字段值与今天之间的增量(以天为单位)。该小部件在编辑模式下变成常规日期或日期时间字段。

  • 支持的字段类型:datedatetime

货币 (monetary)

这是 monetary 类型字段的默认字段类型。它用于显示货币。 如果选项中给出了货币字段,它将使用该字段,否则它将回退到默认货币(在会话中)

  • 支持的字段类型:monetaryfloat

选项:

  • currency_field:另一个字段名称,应该是货币上的 Many2one。

    <field name="value" widget="monetary" options="{'currency_field': 'currency_id'}" />
    
  • hide_trailing_zeros:隐藏最后一个非零数字右侧的零,例如`1.20` 变为 1.2`(默认为 `false)。

    <field name="int_value" options="{'hide_trailing_zeros': true}" />
    
文本 (text)

这是 text 类型字段的默认字段类型。

  • 支持的字段类型:text

密码 (password)

该小部件使用“type="password"”呈现输入内的字段值,隐藏真实值。输入旁边的眼睛按钮允许用户显示或隐藏该值。当字段必须存储敏感数据(例如 API 密钥、令牌)并且默认情况下该值不可见时,此小部件非常有用。

  • 支持的字段类型:chartext

选项:

  • placeholder:当字段为空时在输入中显示的占位符文本。

    <field name="api_key" widget="password" placeholder="Enter your API key"/>
    
句柄 (handle)

该字段的作用是显示为 handle,并允许通过拖放记录来重新排序它们。

警告

必须在记录排序所依据的字段上指定它。

警告

不支持在同一列表上拥有多个带有句柄小部件的字段。

  • 支持的字段类型:integer

电子邮件 (email)

该字段显示电子邮件地址。 使用它的主要原因是它以只读模式呈现为具有正确 href 的锚标记。

  • 支持的字段类型:char

电话 (phone)

该字段显示电话号码。 使用它的主要原因是它在只读模式下呈现为具有正确 href 的锚标记,但仅限于某些情况:我们只想在设备可以呼叫此特定号码时使其可单击。

  • 支持的字段类型:char

网址 (url)

该字段显示一个 url(只读模式)。使用它的主要原因是它被渲染为具有适当 css 类和 href 的锚标记。

此外,可以使用 text 属性自定义锚标记的文本(它不会更改 href 值)。

  • 支持的字段类型:char

<field name="foo" widget="url" text="Some URL" />

选项:

  • website_path:(默认值:false)默认情况下,小部件强制(如果还没有这种情况)href 值以 "http://" 开头,除非此选项设置为 true,从而允许重定向到数据库自己的网站。

域名 (domain)

借助树状界面,domain 字段允许用户构建技术前缀域并实时查看所选记录。在调试模式下,还可以通过输入直接输入前缀字符域(或者构建树状界面不允许的高级域)。

请注意,这仅限于**静态**域(无动态表达式或对上下文变量的访问)。

  • 支持的字段类型:char

选项:

  • model:对应用域的 res_model 进行编码的 char 字段的名称。

  • foldable`(默认值:`false):如果为 true,则域字段将紧凑呈现并在用户交互时自行展开。

  • in_dialog`(默认值:`false):如果为 true,则当用户想要编辑域时,小部件将打开一个对话框,而默认情况下,域编辑器将呈现在值的正下方。

  • count_limit`(默认值:`10000):域小部件执行 search_count 请求来验证域,并指示与其匹配的记录数。在大型表上,此请求的成本可能很高,因此默认情况下,search_count 限制为 10000。

链接按钮 (link_button)

LinkButton 小部件实际上只是显示一个带有图标的范围和作为内容的文本值。该链接是可点击的,将打开一个新的浏览器窗口,其值为 url。

  • 支持的字段类型:char

图像文件 (image)

该小部件用于将二进制值表示为图像。在某些情况下,服务器返回 bin_size 而不是真实图像(bin_size 是表示文件大小的字符串,例如 "6.5kb")。 在这种情况下,小部件将制作具有与服务器上的图像相对应的源属性的图像。

  • 支持的字段类型:binary

选项:

  • preview_image:如果图像仅作为 bin_size 加载,则此选项可用于通知 Web 客户端默认字段名称不是当前字段的名称,而是另一个字段的名称。

    <field name="image" widget="image" options="{'preview_image': 'image_128'}" />
    
  • accepted_file_extensions:用户可以从文件输入对话框中选择的文件扩展名(默认值为`”image/*”`

    (参见:accept attribute on <输入类型=“文件”/>

二进制文件 (binary)

允许保存/下载二进制文件的通用小部件。

  • 支持的字段类型:binary

属性:

  • filename:保存二进制文件将丢失其文件名,因为它只保存二进制值。文件名可以保存在另一个字段中。为此,应将 filename 属性设置为视图中存在的字段。

    <field name="datas" filename="datas_fname" />
    

选项:

  • accepted_file_extensions:用户可以从文件输入对话框中选择的文件扩展名

    (参见:accept attribute on <输入类型=“文件”/>

优先级 (priority)

该小部件呈现为一组星形,允许用户单击它来选择或不选择值。例如,这对于将任务标记为高优先级非常有用。

请注意,此小部件也可以在 readonly 模式下工作,这是不寻常的。

  • 支持的字段类型:selection

图片附件 (attachment_image)

many2one 字段的图像小部件。如果设置了该字段,则该小部件将呈现为具有正确 src url 的图像。该小部件在编辑或只读模式下没有不同的行为,它仅对查看图像有用。

  • 支持的字段类型:many2one

<field name="displayed_image_id" widget="attachment_image" />
标签选择 (label_selection)

该小部件呈现一个简单的不可编辑标签。这仅对显示某些信息有用,对编辑信息无用。

  • 支持的字段类型:selection

选项:

  • classes:从选择值到 CSS 类名的映射

    <field
        name="state"
        widget="label_selection"
        options="{
            'classes': {
                'draft': 'default',
                'cancel': 'default',
                'none': 'danger',
            },
        }"
    />
    
状态选择 (state_selection)

这是一个专门的选择小部件。它假设记录具有一些硬编码字段,存在于视图中:stage_idlegend_normallegend_blockedlegend_done。这主要用于显示和更改项目中任务的状态,并在下拉列表中显示其他信息。

  • 支持的字段类型:selection

<field name="kanban_state" widget="state_selection" />
状态选择 - 列表视图 (list.state_selection)

在列表视图中,state_selection 字段默认显示图标旁边的标签。

  • 支持的字段类型:selection

选项:

  • hide_label:隐藏图标旁边的标签

    <field name="kanban_state" widget="state_selection" options="{'hide_label': true}" />
    
最喜欢的 (boolean_favorite)

该小部件显示为空(或非空)星,具体取决于布尔值。请注意,它也可以在只读模式下进行编辑。

  • 支持的字段类型:boolean

切换 (boolean_toggle)

显示一个表示布尔值的切换开关。这是 boolean 字段的子字段,主要用于具有不同的外观。

  • 支持的字段类型:boolean

统计信息 (statinfo)

该小部件旨在表示 stat button 中的统计信息。它基本上只是一个带有数字的标签。

  • 支持的字段类型:integerfloat

选项:

  • label_field:如果给定,小部件将使用 label_field 的值作为文本。

    <button
        name="%(act_payslip_lines)d"
        icon="fa-money"
        type="action"
    >
        <field
            name="payslip_count"
            widget="statinfo"
            string="Payslip"
            options="{'label_field': 'label_tasks'}"
        />
    </button>
    
百分比饼 (percentpie)

该小部件旨在表示 stat button 中的统计信息。这类似于 statinfo 小部件,但信息以 饼图 表示(从空到满)。 请注意,该值被解释为百分比(0100 之间的数字)。

  • 支持的字段类型:integerfloat

<field name="replied_ratio" string="Replied" widget="percentpie" />
进度条 (progressbar)

将一个值表示为进度条(从 0 到某个值)

  • 支持的字段类型:integerfloat

选项:

  • editable:布尔值确定 value 是否可编辑

  • current_value:从视图中必须存在的字段获取当前值

  • max_value:从视图中必须存在的字段中获取最大值

  • edit_max_value:布尔值确定 max_value 是否可编辑

  • title:栏的标题,显示在栏的顶部

    -> 未翻译,如果必须翻译该术语,请使用 title 属性(不是选项)

<field
    name="absence_of_today"
    widget="progressbar"
    options="{
        'current_value': 'absence_of_today',
        'max_value': 'total_employee',
        'editable': false,
    }"
/>
期刊仪表板图 (dashboard_graph)

这是一个更专业的小部件,可用于显示表示一组数据的图表。例如,它用在会计仪表板看板视图中。

它假设该字段是一组数据的 JSON 序列化。

  • 支持的字段类型:char

属性:

  • graph_type:字符串,可以是 "line""bar"

    <field name="dashboard_graph_data" widget="dashboard_graph" graph_type="line" />
    
王牌编辑 (ace)

该小部件旨在用于文本字段。它提供了用于编辑 XML 和 Python 的 Ace Editor。

  • 支持的字段类型:chartext

徽章 (badge)

显示引导徽章药丸内的值。

  • 支持的字段类型:charselectionmany2one

默认情况下,徽章具有浅灰色背景,但可以使用 Decoration 机制进行自定义。例如,要在给定条件下显示红色徽章:

<field name="foo" widget="badge" decoration-danger="state == 'cancel'" />

关系字段

选择 (selection)

  • 支持的字段类型:selection

属性:

  • placeholder:一个字符串,用于在未选择值时显示一些信息

    <field name="tax_id" widget="selection" placeholder="Select a tax" />
    
收音机 (radio)

这是 FielSelection 的子字段,但专门用于将所有有效选项显示为单选按钮。

请注意,如果在 Many2one 记录上使用,则将执行更多 rpc 来获取相关记录的 name_gets。

  • 支持的字段类型:selectionmany2one

选项:

  • horizontal:如果`true`,单选按钮将水平显示。

    <field name="recommended_activity_type_id" widget="radio" options="{'horizontal': true}"/>
    
徽章选择 (selection_badge)

这是 selection 字段的子字段,但专门用于将所有有效选择显示为矩形徽章。

  • 支持的字段类型:selectionmany2one

<field name="recommended_activity_type_id" widget="selection_badge" />
多对一 (many2one)

Many2one 字段的默认小部件。

  • 支持的字段类型:many2one

属性:

  • can_create:允许创建相关记录(优先于 no_create 选项)

  • can_write:允许编辑相关记录(默认:true

选项:

  • quick_create:允许快速创建相关记录(默认:true

  • no_create:防止创建相关记录 - 隐藏 创建“xxx”创建和编辑 下拉菜单项(默认值:false

  • no_quick_create:防止快速创建相关记录 - 隐藏 创建“xxx” 下拉菜单项(默认值:false

  • no_create_edit:隐藏 创建和编辑 下拉菜单项(默认值:false

  • create_name_field:创建相关记录时,如果设置该选项,则`create_name_field`的值将填充为输入的值(默认:name

  • always_reload:布尔值,默认为 false。如果 true,小部件将始终执行额外的 name_get 来获取其名称值。这用于覆盖 name_get 方法的情况(请不要这样做)

  • no_open:布尔值,默认为 false。如果设置为 true,则在单击记录时,many2one 将不会重定向记录(在只读模式下)

<field name="currency_id" options="{'no_create': true, 'no_open': true}" />
Many2one 条形码 (many2one_barcode)

many2one 字段的小部件允许从移动设备 (Android/iOS) 打开相机来扫描条形码。

many2one 字段的专业化,允许用户使用本机相机扫描条形码。然后它使用 name_search 来搜索该值。

如果设置了此小部件并且用户未使用移动应用程序,它将回退到常规 many2one (Many2OneField)

  • 支持的字段类型:many2one

Many2one 头像 (many2one_avatar)

此小部件仅在指向继承自 image.mixin 的模型的 many2one 字段上受支持。在只读模式下,它会在其 display_name 旁边显示相关记录的图像。请注意,在这种情况下,display_name 不是可点击的链接。在编辑中,它的行为与常规 many2one 完全相同。

  • 支持的字段类型:many2one

Many2one 头像用户 (many2one_avatar_user)

该小部件是 Many2OneAvatar 的特化。单击头像时,我们会打开与相应用户的聊天窗口。此小部件只能在指向 res.users 模型的 many2one 字段上设置。

  • 支持的字段类型:many2one`(指向`res.users

Many2one 头像员工 (many2one_avatar_employee)

many2one_avatar_user 相同,但对于指向 hr.employeemany2one 字段。

  • 支持的字段类型:many2one`(指向`hr.employee

多对多 (many2many)

many2many 字段的默认小部件。

  • 支持的字段类型:many2many

属性:

  • mode:字符串,默认显示视图

  • domain:将数据限制到特定域

选项:

  • create_text:允许自定义添加新记录时显示的文本

  • link:确定是否可以将记录添加到关系中的域(默认值:true)。

  • unlink:确定是否可以从关系中删除记录的域(默认值:true)。

多对多二进制文件 (many2many_binary)

该小部件可帮助用户同时上传或删除一个或多个文件。

请注意,此小部件特定于型号 ir.attachment

  • 支持的字段类型:many2many

选项:

  • accepted_file_extensions:用户可以从文件输入对话框中选择的文件扩展名

    (参见:accept attribute on <输入类型=“文件”/>

多对多标签 (many2many_tags)

many2many 字段显示为标签列表。

  • 支持的字段类型:many2many

选项:

  • create:决定是否可以创建新标签的域(默认值:true)。

    <field name="category_id" widget="many2many_tags" options="{'create': [['some_other_field', '>', 24]]}" />
    
  • color_field:数字字段的名称,应出现在视图中。将根据其值选择颜色。

    <field name="category_id" widget="many2many_tags" options="{'color_field': 'color'}" />
    
  • no_edit_color:设置为 true 以消除更改标签颜色的可能性(默认值:false)。

    <field name="category_id" widget="many2many_tags" options="{'color_field': 'color', 'no_edit_color': true}" />
    
  • edit_tags:设置为 true 以添加通过单击标签来更新标签相关记录的可能性。 (默认值:false)。

    <field name="category_id" widget="many2many_tags" options="{'edit_tags': true}" />
    
Many2many 标签 - 表单视图 (form.many2many_tags)

表单视图的 many2many_tags 小部件的专业化。它有一些额外的代码来允许编辑标签的颜色。

  • 支持的字段类型:many2many

Many2many 标签 - 看板视图 (kanban.many2many_tags)

看板视图的 many2many_tags 小部件的专业化。

  • 支持的字段类型:many2many

多对多复选框 (many2many_checkboxes)

该字段显示复选框列表并允许用户选择选项的子集。请注意,显示值的数量限制为 100。此限制不可自定义。它只是允许处理极端情况,即该小部件被错误地设置在具有巨大代码模型的字段上。在这些情况下,列表视图更合适,因为它允许分页和过滤。

  • 支持的字段类型:many2many

一对多 (one2many)

one2many 字段的默认小部件。它通常在子列表视图或子看板视图中显示数据。

  • 支持的字段类型:one2many

选项:

  • create:决定是否可以创建相关记录的域(默认:true)。

  • delete:决定是否可以删除相关记录的域(默认:true)。

    <field name="turtles" options="{'create': [['some_other_field', '>', 24]]}" />
    
  • create_text:用于自定义“添加”标签/文本的字符串。

    <field name="turtles" options="{'create_text': 'Add turtle'}" />
    
状态栏 (statusbar)

这是特定于表单视图的字段。它是许多表单顶部的栏,代表流程,并允许选择特定状态。

  • 支持的字段类型:selectionmany2one

参考 (reference)

reference 字段是 select(针对模型)和 many2one 字段(针对其值)的组合。 它允许选择任意模型上的记录。

  • 支持的字段类型:charreference

选项:

  • model_fieldir.model 的名称,包含可选择的记录的型号。设置此选项后,不会显示 reference 字段的选择部分。

小部件

功能区 (web_ribbon)

例如,该小部件在看板卡或表单视图表的右上角显示一个功能区,以指示存档记录。

<widget name="web_ribbon" title="Archived" bg_color="text-bg-danger"/>

属性:

  • title:功能区中显示的文本。

  • tooltip:功能区工具提示中显示的文本。

  • bg-class:在功能区上设置的类名,通常用于定义功能区的颜色。

工作日 (week_days)

该小部件显示工作日的复选框列表,每天 1 个复选框,并允许用户选择选项的子集。

<widget name="week_days" />

客户行动

客户端操作是一个可以在 Web 客户端中显示为主要元素的组件,占据导航栏下方的所有空间,就像 act_window_action 一样。当您需要一个与现有视图或特定模型没有紧密链接的组件时,这非常有用。 例如,讨论应用程序是客户端操作。

客户端操作是一个具有多种含义的术语,具体取决于上下文:

  • 从服务器的角度来看,它是模型 ir_action 的记录,具有 char 类型的字段 tag

  • 从 Web 客户端的角度来看,它是一个 Owl 组件,在操作注册表中注册在与其标签相同的键下

每当菜单项与客户端操作关联时,打开它只会从服务器获取操作定义,然后在操作注册表中查找其标签以获取组件定义。然后,该组件将由操作容器呈现。

添加客户端操作

客户端操作是一个组件,它将控制导航栏下方的屏幕部分。定义客户端操作就像创建 Owl 组件并将其添加到操作注册表一样简单。

import { registry } from "@web/core/registry";
class MyClientAction extends Component { ... }
registry.category("actions").add("my-custom-action", ClientAction);

然后,要在Web客户端中使用客户端操作,我们需要创建一个客户端操作记录(模型``ir.actions.client``) with the proper ``tag``属性的记录:

<record id="my_client_action" model="ir.actions.client">
    <field name="name">Some Name</field>
    <field name="tag">my-custom-action</field>
</record>