首页 > 语言 > JavaScript > 正文

从源码看angular/material2 中 dialog模块的实现方法

2024-05-06 15:25:31
字体:
来源:转载
供稿:网友

本文将探讨material2中popup弹窗即其Dialog模块的实现。

使用方法

    引入弹窗模块 自己准备作为模板的弹窗内容组件 在需要使用的组件内注入 MatDialog 服务 调用 open 方法创建弹窗,并支持传入配置、数据,以及对关闭事件的订阅

深入源码

进入material2的源码,先从 MatDialog 的代码入手,找到这个 open 方法:

open<T>( componentOrTemplateRef: ComponentType<T> | TemplateRef<T>, config?: MatDialogConfig): MatDialogRef<T> { // 防止重复打开 const inProgressDialog = this.openDialogs.find(dialog => dialog._isAnimating()); if (inProgressDialog) {  return inProgressDialog; } // 组合配置 config = _applyConfigDefaults(config); // 防止id冲突 if (config.id && this.getDialogById(config.id)) {  throw Error(`Dialog with id "${config.id}" exists already. The dialog id must be unique.`); } // 第一步:创建弹出层 const overlayRef = this._createOverlay(config); // 第二步:在弹出层上添加弹窗容器 const dialogContainer = this._attachDialogContainer(overlayRef, config); // 第三步:把传入的组件添加到创建的弹出层中创建的弹窗容器中 const dialogRef = this._attachDialogContent(componentOrTemplateRef, dialogContainer, overlayRef, config); // 首次弹窗要添加键盘监听 if (!this.openDialogs.length) {  document.addEventListener('keydown', this._boundKeydown); } // 添加进队列 this.openDialogs.push(dialogRef); // 默认添加一个关闭的订阅 关闭时要移除此弹窗 // 当是最后一个弹窗时触发全部关闭的订阅并移除键盘监听 dialogRef.afterClosed().subscribe(() => this._removeOpenDialog(dialogRef)); // 触发打开的订阅 this.afterOpen.next(dialogRef); return dialogRef;}

总体看来弹窗的发起分为三部曲:

    创建一个弹出层(其实是一个原生DOM,起宿主和入口的作用) 在弹出层上创建弹窗容器组件(负责提供遮罩和弹出动画) 在弹窗容器中创建传入的弹窗内容组件(负责提供内容)

弹出层的创建

对于其他组件,仅仅封装模板以及内部实现就足够了,最多还要增加与父组件的数据、事件交互,所有这些事情,单使用angular Component就足够实现了,在何处使用就将组件选择器放到哪里去完事。

但对于弹窗组件,事先并不知道会在何处使用,因此不适合实现为一个组件后通过选择器安放到页面的某处,而应该将其作为弹窗插座放置到全局,并通过服务来调用。

material2也要面临这个问题,这个弹窗插座是避免不了的,那就在内部实现它,在实际调用弹窗方法时动态创建这个插座就可以了。要实现效果是:对用户来说只是在单纯调用一个 open 方法,由material2内部来创建一个弹出层,并在这个弹出层上创建弹窗。

找到弹出层的创建代码如下:

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选