跳到主要内容

OWL - Dialog

Note

OWL - Dialog

--version: 16.0

Dialog模板(xml)

首先来看Dialog的模板,整体结构可以划分成header/main/footer,其中header/footer可以不显示,main是必然会显示的。

Dialog有三个slot: (按需通过t-set-slot修改)

  1. default: 弹窗主体内容
  2. header: 弹窗顶部
  3. footer: 弹窗底部

header:

header中默认内容主要是title信息与关闭按钮。

(如果需要对Dialog的header进行修改,可以通过slot进行修改;或者修改Dialog的template:web.Dialog.header

main:

弹窗主体部分。由于main标签内是slot(default), 所以可以直接在<Dialog></Dialog>标签内直接添加内容。

footer:

弹窗底部部分,默认内容是一个确定按钮。通常自定义button会修改footer,通过t-set-slot进行修改。

Dialog组件(js)

Dialog.props:

name说明默认值
contentClass弹窗最外层div样式""
bodyClass弹窗main主体样式""
fullscreen是否全屏false
footer是否显示底部true
header是否显示头部true
size弹窗大小"lg"
technical是否技术弹窗true
title弹窗标题"Odoo"
modalRef弹窗引用
slotsSlot
withBodyPadding是否有弹窗主体paddingtrue

dialogService

dialogService可以通过一下方式调用:

import { useService, useOwnedDialogs } from "@web/core/utils/hooks";
// ...

class XX extends Component {
setup() {
this.dialogService = useService("dialog");
// this.dialogService.add();
this.addDialog = useOwnedDialogs();
// this.addDialog = this.dialogService.add;
}
}

dialogService提供一个add函数来打开Dialog页面。

function add(dialogClass, props, options = {}){
// ...
}

add函数接收三个参数:

  1. dialogClass: Dialog组件
  2. props: Dialog参数
  3. options: 弹窗配置项(原生只处理一个参数:onClose,该参数的类型为function,作用为点击弹窗关闭按钮/默认按钮时调用)

源码

addons/web/static/src/core/dialog/dialog.js
/** @odoo-module **/

import { useHotkey } from "@web/core/hotkeys/hotkey_hook";
import { useActiveElement } from "../ui/ui_service";
import { useForwardRefToParent } from "@web/core/utils/hooks";

import { Component, useChildSubEnv, useState } from "@odoo/owl";
export class Dialog extends Component {
setup() {
this.modalRef = useForwardRefToParent("modalRef");
useActiveElement("modalRef");
this.data = useState(this.env.dialogData);
useHotkey("escape", () => {
this.data.close();
});
this.id = `dialog_${this.data.id}`;
useChildSubEnv({ inDialog: true, dialogId: this.id, closeDialog: this.data.close });

owl.onWillDestroy(() => {
if (this.env.isSmall) {
this.data.scrollToOrigin();
}
});
}

get isFullscreen() {
return this.props.fullscreen || this.env.isSmall;
}
}
Dialog.template = "web.Dialog";
Dialog.props = {
contentClass: { type: String, optional: true },
bodyClass: { type: String, optional: true },
fullscreen: { type: Boolean, optional: true },
footer: { type: Boolean, optional: true },
header: { type: Boolean, optional: true },
size: { type: String, optional: true, validate: (s) => ["sm", "md", "lg", "xl"].includes(s) },
technical: { type: Boolean, optional: true },
title: { type: String, optional: true },
modalRef: { type: Function, optional: true },
slots: {
type: Object,
shape: {
default: Object, // Content is not optional
header: { type: Object, optional: true },
footer: { type: Object, optional: true },
},
},
withBodyPadding: { type: Boolean, optional: true },
};
Dialog.defaultProps = {
contentClass: "",
bodyClass: "",
fullscreen: false,
footer: true,
header: true,
size: "lg",
technical: true,
title: "Odoo",
withBodyPadding: true,
};