自定义一个字段

对现有字段组件进行子类化

让我们举一个例子,我们想要扩展 BooleanField 以创建一个显示“迟到!”的布尔字段。每当选中该复选框时,就会显示为红色。

  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 传递的标准 props,例如用于更新值的 update 函数、模型中字段的 typereadonly 布尔值等。

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

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

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

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

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