自定义字段

子类化现有的字段组件

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

  1. 创建一个新的小部件组件,继承所需的字段组件。

    late_order_boolean_field.js
    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 {
       static 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">
            <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. 在视图架构中将小部件作为字段的属性添加。

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

创建一个新的字段组件

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

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

    my_text_field.js
    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 {
       static template = xml`
          <input t-att-id="props.id" class="text-danger" t-att-value="props.value" onChange.bind="onChange" />
       `;
       static props = { ...standardFieldProps };
       static supportedTypes = ["char"];
    
       /**
       * @param {boolean} newValue
       */
       onChange(newValue) {
          this.props.update(newValue);
       }
    }
    

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

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

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

    这将视图架构中的小部件名称映射到其实际组件。

  3. 在视图架构中将小部件作为字段的属性添加。

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