第二章 图片预览

Odoo原生虽然支持附件的预览,但是并不支持表单中的图片预览,因此我们在开源模块的基础上制作了自己的图片预览模块mommy_image_preview。

模块的基本用法

该模块的用法如下,在图片字段的视图文件中,使用image_preview部件。

<field name="image_1920" widget="image_preview" options="{'size':[180,180]}">

options.size用来控制图片预览的默认大小。

模块原理

我们来看一下模块的原理。首先定义了一个部件的视图:

<templates id="template" xml:space="preserve">
    <t t-name="mommy_image_preview.ImagePreviewField" t-inherit="web.ImageField" t-inherit-mode="primary" owl="1">
        <xpath expr="//img[hasclass('img')]" position="attributes">
            <attribute name="t-on-click">onClickImage</attribute>
        </xpath>
    </t>
</templates>

该视图继承自原生ImageField部件,在img元素上添加了一个click事件的监听。

export class ImagePreviewField extends ImageField {
    static template = "mommy_image_preview.ImagePreviewField";
    setup() {
        super.setup();
        this.fileViewer = useFileViewer();
    }
    onClickImage() {
        if (!this.props.record.data[this.props.name]){
            return;
        }
        const attachment = {defaultSource: this.lastURL, isViewable:true, isImage:true, displayName: ''}
        if (isBinarySize(this.props.record.data[this.props.name])) {
            attachment['downloadUrl'] = this.lastURL;
        }
        const attachments = [attachment];
        this.fileViewer.open(attachment, attachments);
    }
}

然后定了一个图片预览组件ImagePreviewField,该部件在setup方法里初始化了一个文件预览的钩子(此钩子为odoo原生代码)。

然后在click事件中,将图片的URL路径传入给fileViewer方法进行打开预览。

export const imagePreviewField = {
    component: ImagePreviewField,
    displayName: _t("Image"),
    supportedOptions: [
        {
            label: _t("Reload"),
            name: "reload",
            type: "boolean",
            default: true,
        },
        {
            label: _t("Enable zoom"),
            name: "zoom",
            type: "boolean",
        },
        {
            label: _t("Zoom delay"),
            name: "zoom_delay",
            type: "number",
            help: _t("Delay the apparition of the zoomed image with a value in milliseconds"),
        },
        {
            label: _t("Accepted file extensions"),
            name: "accepted_file_extensions",
            type: "string",
        },
        {
            label: _t("Size"),
            name: "size",
            type: "selection",
            choices: [
                { label: _t("Small"), value: "[0,90]" },
                { label: _t("Medium"), value: "[0,180]" },
                { label: _t("Large"), value: "[0,270]" },
            ],
        },
        {
            label: _t("Preview image"),
            name: "preview_image",
            type: "field",
            availableTypes: ["binary"],
        },
    ],
    supportedTypes: ["binary"],
    fieldDependencies: [{ name: "write_date", type: "datetime" }],
    isEmpty: () => false,
    extractProps: ({ attrs, options }) => ({
        enableZoom: options.zoom,
        zoomDelay: options.zoom_delay,
        previewImage: options.preview_image,
        acceptedFileExtensions: options.accepted_file_extensions,
        width: options.size && Boolean(options.size[0]) ? options.size[0] : attrs.width,
        height: options.size && Boolean(options.size[1]) ? options.size[1] : attrs.height,
        reload: "reload" in options ? Boolean(options.reload) : true,
    }),
};


registry.category("fields").add("image_preview", imagePreviewField);

最后是定义了一个imagePreviewField字段,该字段使用ImagePreviewField组件。最后将此字段注册到字段中。

图片预览非钩子用法

在OWL环境中我们可以使用上述的方法进行调用。但是如果是在传统WC环境的中,由于钩子的初始化不能脱离setup方法,导致我们无法在传统的WC环境中使用(例如门户环境的publicWidget)。

解决这个问题的方法是我们不用钩子,而是自己实现预览方法:

const viewerId = `web.file_viewer${fileViewerId++}`
registry.category("main_components").add(viewerId, {
    Component: FileViewer,
    props: {
        files: [{
            isImage: true,
            isViewable: true,
            displayName: url,
            defaultSource: url,
            downloadUrl: url,
        }],
        startIndex: 0,
        close: () => {
            registry.category('main_components').remove(viewerId);
        },
    },
})

我们在图片的单击事件中,使用FileViewer组件,传入相应的文件参数和URL,即可完成图片的预览。

results matching ""

    No results matching ""