详解angular2封装material2对话框组件


Posted in Javascript onMarch 03, 2017

1. 说明

angular-material2自身文档不详,控件不齐,使用上造成了很大的障碍。这里提供一个方案用于封装我们最常用的alert和confirm组件。

2. 官方使用方法之alert

①编写alert内容组件

@Component({
template : `<p>你好</p>`
})
export class AlertComponent {

 constructor(){
 }
}

②在所属模块上声明

//必须声明两处
declarations: [ AlertComponent],
entryComponents : [ AlertComponent]

③使用MdDialg.open方法打开

//注入MdDialog对象
constructor(private mdDialog : MdDialog) { }
//打开
this.mdDialog.open(AlertComponent)

3. 官方使用方法之confirm

①编写confirm内容组件

@Component({
template : `<div md-dialog-title>'确认操作'</div>
      <div md-dialog-content>确认执行操作?</div>
      <div md-dialog-actions>
       <button md-button (click)="mdDialogRef.close('ok')">确认</button>
       <button md-button (click)="mdDialogRef.close('cancel')">取消</button>
      </div>`
})
export class ConfirmComponent {
 constructor(private mdDialogRef : MdDialogRef<DialogComponent>){ }
}

②在所属模块上声明

//必须声明两处
declarations: [ ConfirmComponent],
entryComponents : [ ConfirmComponent]

③使用MdDialog.open打开并订阅相关事件

//注入MdDialog对象
constructor(private mdDialog : MdDialog) { }
//打开
this.mdDialog.open(ConfirmComponent).subscribe(res => {
 res === 'ok' && dosomething
});

4. 分析

如2、3所示,使用material2的对话框组件相当繁琐,甚至仅仅打开一个不同的alert都要声明一个独立的组件,可用性很差。但也不是毫无办法。

MdDialog.open原型:

open<T>(componentOrTemplateRef: ComponentType<T> | TemplateRef<T>, config?: MdDialogConfig): MdDialogRef<T>;

其中MdDialogConfig:

export declare class MdDialogConfig {
  viewContainerRef?: ViewContainerRef;
  /** The ARIA role of the dialog element. */
  role?: DialogRole;
  /** Whether the user can use escape or clicking outside to close a modal. */
  disableClose?: boolean;
  /** Width of the dialog. */
  width?: string;
  /** Height of the dialog. */
  height?: string;
  /** Position overrides. */
  position?: DialogPosition;
  /** Data being injected into the child component. */
  data?: any;
}

具体每一个配置项有哪些用途可以参考官方文档,这里data字段,说明了将会被携带注入子组件,也即被open打开的component组件。怎么获取呢?

config : any;
constructor(private mdDialogRef : MdDialogRef<AlertComponent>){
  this.config = mdDialogRef.config.data || {};
}

有了它我们就可以定义一个模板型的通用dialog组件了。

5. 定义通用化的组件

//alert.component.html
<div class="title" md-dialog-title>{{config?.title || '提示'}}</div>
<div class="content" md-dialog-content>{{config?.content || ''}}</div>
<div class="actions" *ngIf="!(config?.hiddenButton)" md-dialog-actions>
 <button md-button (click)="mdDialogRef.close()">{{config?.button || '确认'}}</button>
</div>
//alert.component.scss
.title, .content{
 text-align: center;
}
.actions{
 display: flex;
 justify-content: center;
}
//alert.component.ts
@Component({
 selector: 'app-alert',
 templateUrl: './alert.component.html',
 styleUrls: ['./alert.component.scss']
})
export class AlertComponent {

 config : {};

 constructor(private mdDialogRef : MdDialogRef<AlertComponent>){
  this.config = mdDialogRef.config.data || {};
 }

}

我们将模板的一些可置换内容与config一些字段进行关联,那么我们可以这么使用:

constructor(private mdDialog : MdDialog) { }

let config = new MdDialogConfig();
config.data = {
  content : '你好'
}
this.mdDialog.open(AlertComponent, config)

依然繁琐,但至少我们解决了对话框组件复用的问题。

我们可以声明一个新的模块,暂且起名为CustomeDialogModule,然后将component声明在此模块里,再将此模块声明到AppModule,这样可以避免AppModule的污染,保证我们的对话框组件独立可复用。

6. 二次封装

如果仅仅是上面的封装,可用性依然很差,工具应当尽可能的方便,所以我们有必要再次进行封装

首先在CustomDialogModule建一个服务,暂且起名为CustomDialogService

@Injectable()
export class CustomDialogService {

 constructor(private mdDialog : MdDialog) { }

 //封装confirm,直接返回订阅对象
 confirm(contentOrConfig : any, title ?: string) : Observable<any>{
  let config = new MdDialogConfig();
  if(contentOrConfig instanceof Object){
   config.data = contentOrConfig;
  }else if((typeof contentOrConfig) === 'string'){
   config.data = {
    content : contentOrConfig,
    title : title
   }
  }
  return this.mdDialog.open(DialogComponent, config).afterClosed();
 }

 //同
 alert(contentOrConfig : any, title ?: string) : Observable<any>{
  let config = new MdDialogConfig();
  if(contentOrConfig instanceof Object){
   config.data = contentOrConfig;
  }else if((typeof contentOrConfig) === 'string'){
   config.data = {
    content : contentOrConfig,
    title : title
   }
  }
  return this.mdDialog.open(AlertComponent, config).afterClosed();
 }

我们把它注册在CustomDialogModule里的provides,它就可以被全局使用了。

用法:

constructor(dialog : CustomDialogService){}

this.dialog.alert('你好');
this.dialog.alert('你好','标题');
this.dialog.alert({
  content : '你好',
  title : '标题',
  button : 'ok'
});
this.dialog.confirm('确认吗').subscribe(res => {
  res === 'ok' && dosomething
});

按照这种思路我们还可以封装更多组件,例如模态框,toast等

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
利用jQuery 实现GridView异步排序、分页的代码
Feb 06 Javascript
JavaScript字符串对象slice方法入门实例(用于字符串截取)
Oct 16 Javascript
AngularJS中的过滤器使用详解
Jun 16 Javascript
CSS图片响应式 垂直水平居中
Aug 14 Javascript
JS实现探测网站链接的方法【测试可用】
Nov 08 Javascript
AngularJS定时器的使用与移除操作方法【interval与timeout】
Dec 14 Javascript
jquery表单验证插件validation使用方法详解
Jan 20 Javascript
使用react实现手机号的数据同步显示功能的示例代码
Apr 03 Javascript
vue router动态路由设置参数可选问题
Aug 21 Javascript
js get和post请求实现代码解析
Feb 06 Javascript
Element Tooltip 文字提示的使用示例
Jul 26 Javascript
Openlayers绘制聚合标注
Sep 28 Javascript
jQuery插件jqGrid动态获取列和列字段的方法
Mar 03 #Javascript
AngularJS表格样式简单设置方法示例
Mar 03 #Javascript
AngularJS表格添加序号的方法
Mar 03 #Javascript
JS实现双击内容变为可编辑状态
Mar 03 #Javascript
jquery表单验证实例仿Toast提示效果
Mar 03 #Javascript
JavaScript的for循环中嵌套一个点击事件的问题解决
Mar 03 #Javascript
JavaScript控制输入框中只能输入中文、数字和英文的方法【基于正则实现】
Mar 03 #Javascript
You might like
PHP中的替代语法简介
2014/08/22 PHP
ThinkPHP 表单自动验证运用示例
2014/10/13 PHP
php查询操作实现投票功能
2016/05/09 PHP
laravel5.6实现数值转换
2019/10/23 PHP
JavaScript cookie的设置获取删除详解
2014/02/11 Javascript
浅析JavaScript基本类型与引用类型
2014/05/28 Javascript
javascript判断数组内是否重复的方法
2015/04/21 Javascript
JS实现的系统调色板完整实例
2016/12/21 Javascript
详解Javascript百度地图接口开发文档中的类和方法
2017/02/07 Javascript
JavaScript闭包_动力节点Java学院整理
2017/06/27 Javascript
使用vue官方提供的模板vue-cli搭建一个helloWorld案例分析
2018/01/16 Javascript
详解基于Vue-cli搭建的项目如何和后台交互
2018/06/29 Javascript
vue项目引入字体.ttf的方法
2018/09/28 Javascript
angularJs利用$scope处理升降序的方法
2018/10/08 Javascript
JS实现checkbox互斥(单选)功能示例
2019/05/04 Javascript
JS使用正则表达式实现常用的表单验证功能分析
2020/04/30 Javascript
详细分析Node.js 模块系统
2020/06/28 Javascript
[01:06:25]Secret vs Liquid 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
Python3基础之基本运算符概述
2014/08/13 Python
python实现的简单FTP上传下载文件实例
2015/06/30 Python
python登录豆瓣并发帖的方法
2015/07/08 Python
python-opencv 将连续图片写成视频格式的方法
2019/01/08 Python
Python面向对象之私有属性和私有方法应用案例分析
2019/12/31 Python
PyCharm取消波浪线、下划线和中划线的实现
2020/03/03 Python
Python实现检测文件的MD5值来查找重复文件案例
2020/03/12 Python
python列表的逆序遍历实现
2020/04/20 Python
python七种方法判断字符串是否包含子串
2020/08/18 Python
python 第三方库paramiko的常用方式
2021/02/20 Python
amazeui模态框弹出后立马消失并刷新页面
2020/08/19 HTML / CSS
英国Office鞋店德国网站:在线购买鞋子、靴子和运动鞋
2018/12/19 全球购物
Linden Leaves官网:新西兰纯净护肤品
2020/12/20 全球购物
2014年终个人工作总结
2014/11/07 职场文书
2015年财务工作总结范文
2015/03/31 职场文书
办公用品质量保证书
2015/05/11 职场文书
电影雷锋观后感
2015/06/10 职场文书
go语言基础 seek光标位置os包的使用
2021/05/09 Golang