第十章 字段

与经典WC实现不同,新的WC中不再有Widget的实体概念,同样也不再有字段的实体概念,在新的WC实现中,所谓的字段实际上也是一种组件。

字段的定义

我们还是先来看OWL中字段的定义:

export class Field extends Component {
    setup() {
        this.FieldComponent = this.props.fieldInfo.FieldComponent;
        if (!this.FieldComponent) {
            const fieldType = this.props.record.fields[this.props.name].type;
            this.FieldComponent = getFieldClassFromRegistry(fieldType, this.props.type);
        }
    }
    ...

由此我们可以知道,字段实际上就是一种组件。

创建字段

知道了字段的属性,那么我们如何创建一个新的字段类型呢?这里我们以微信公众号模块的升级为例,来说明如何创建一个OWL的字段。由于odoo16.0不再兼容经典的WC实现,因此我们之前版本的代码已经不能在16.0上面使用,我们需要使用OWL的方式将我们的代码升级。

首先,我们需要创建一个新的字段类型WeChatMedia:

import { registry } from '@web/core/registry';
import { standardFieldProps } from '@web/views/fields/standard_field_props';

const { Component,useRef } = owl;

export class WechatMedia extends Component {

    setup(){
        this.input = useRef("input");
    }
    ...

WechatMedia.template = 'mommy_wechat_media.WechatMedia';
WechatMedia.props = {
    ...standardFieldProps,
}

registry.category('fields').add('wechatmedia', WechatMedia);

我们首先创建了WechatMedia这个类型的字段组件,然后设置了它的初始属性和若干业务逻辑方法(此处省略)。然后,我们指定了它的模版名称,并继承了标准字段所拥有的属性,最后将其注册到了字段注册中心。

然后我们来看模版的代码:

<t t-name="mommy_wechat_media.WechatMedia" owl="1">
    <div t-if="!props.readonly">
        <span class="wechat_form_field"></span>
        <form id="wechatform" class="wechat_form_field_upload"  enctype="multipart/form-data">
            <div>
                <input type="file" class="o_form_input wechat_file" t-ref="input"/>
                <button class="btn btn-sm btn-primary o_select_file_button" title="Select" t-on-click="()=> this.uploadWeChat()">上传媒体文件</button>
            </div>
        </form>
    </div>
    <div t-else="">
        <span t-esc="formattedValue"/>
    </div>
</t>

我们根据字段是否要求只读的属性,将其显示为了两种渲染形态,如果字段没有只读属性,那么它将显示为一个文件选择按钮和一个文件上传按钮。否则,它只会显示一个静态的文本(微信媒体文件ID)。这是一个非常重要的点,我们在进行创建自己的字段的时候都要考虑到是否会设置为只读。

results matching ""

    No results matching ""