自定义字段

子类化现有字段组件

让我们举一个例子,我们想要扩展 BooleanField 来创建一个布尔字段,每当复选框被选中时,显示红色的 “Late!”。

  1. 创建一个扩展所需字段组件的新小部件组件。

    late_order_boolean_field.js
    /** @odoo-module */
    
    import { registry } from "@web/core/registry";
    import { BooleanField } from "@web/views/fields/boolean/boolean_field";
    import { Component, xml } from "@odoo/owl";
    
    class LateOrderBooleanField extends BooleanField {}
    LateOrderBooleanField.template = "my_module.LateOrderBooleanField";
    
  2. 创建字段模板。

    该组件使用一个名为 my_module.LateOrderBooleanField 的新模板。通过继承 BooleanField 的当前模板来创建它。

    late_order_boolean_field.xml
    <?xml version="1.0" encoding="UTF-8" ?>
    <templates xml:space="preserve">
        <t t-name="my_module.LateOrderBooleanField" t-inherit="web.BooleanField" owl="1">
            <xpath expr="//CheckBox" position="after">
                  <span t-if="props.value" class="text-danger"> Late! </span>
            </xpath>
        </t>
    </templates>
    
  3. 将组件注册到字段注册表中。

    late_order_boolean_field.js
    registry.category("fields").add("late_boolean", LateOrderBooleanField);
    
  4. 将小部件添加到视图arch中,作为字段的属性。

    <field name="somefield" widget="late_boolean"/>
    

创建一个新的字段组件

假设我们想要创建一个以红色显示简单文本的字段。

  1. 创建一个新的Owl组件,代表我们的新字段

    my_text_field.js
    /** @odoo-module */
    
    import { standardFieldProps } from "@web/views/fields/standard_field_props";
    import { Component, xml } from "@odoo/owl";
    import { registry } from "@web/core/registry";
    
    export class MyTextField extends Component {
    
        /**
        * @param {boolean} newValue
        */
        onChange(newValue) {
            this.props.update(newValue);
        }
    }
    
    MyTextField.template = xml`
        <input t-att-id="props.id" class="text-danger" t-att-value="props.value" onChange.bind="onChange" />
    `;
    MyTextField.props = {
        ...standardFieldProps,
    };
    MyTextField.supportedTypes = ["char"];
    

    导入的 standardFieldProps 包含了由 View 传递的标准属性,例如 update 函数用于更新值,模型中字段的 typereadonly 布尔值等等。

  2. 在同一个文件中,将组件注册到字段注册表中。

    my_text_field.js
    registry.category("fields").add("my_text_field", MyTextField);
    

    这将arch中的小部件名称映射到其实际组件。

  3. 将小部件添加到视图arch中,作为字段的属性。

    <field name="somefield" widget="my_text_field"/>