详解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 相关文章推荐
JavaScript 参考教程
Dec 29 Javascript
JavaScript传递变量: 值传递?引用传递?
Feb 22 Javascript
利用js 进行输入框自动匹配字符的小例子
Jun 29 Javascript
利用JS判断用户是否上网(连接网络)
Dec 23 Javascript
Node.js中require的工作原理浅析
Jun 24 Javascript
jQuery+css3动画属性制作猎豹浏览器宽屏banner焦点图
Mar 16 Javascript
浅谈JavaScript的Polymer框架中的事件绑定
Jul 29 Javascript
javascript RegExp 使用说明
May 21 Javascript
JS双击变input框批量修改内容
Dec 12 Javascript
vue.js 实现点击展开收起动画效果
Jul 07 Javascript
Vue实现点击当前元素以外的地方隐藏当前元素(实现思路)
Dec 04 Javascript
vue使用nprogress加载路由进度条的方法
Jun 04 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迅雷、快车、旋风下载专用链转换代码
2010/06/15 PHP
php调用nginx的mod_zip模块打包ZIP文件
2014/06/11 PHP
PHP+MYSQL会员系统的开发实例教程
2014/08/23 PHP
浅谈php正则表达式中的非贪婪模式匹配的使用
2014/11/25 PHP
php实现两表合并成新表并且有序排列的方法
2014/12/05 PHP
php扩展开发入门demo示例
2019/09/23 PHP
laravel 获取当前url的别名方法
2019/10/11 PHP
jQuery 1.8 Release版本发布了
2012/08/14 Javascript
js模仿windows桌面图标排列算法具体实现(附图)
2013/06/16 Javascript
用nodejs实现PHP的print_r函数代码
2014/03/14 NodeJs
上传图片js判断图片尺寸和格式兼容IE
2014/09/01 Javascript
一个JavaScript获取元素当前高度的实例
2014/10/29 Javascript
JS数组array元素的添加和删除方法代码实例
2015/06/01 Javascript
javascript弹性运动效果简单实现方法
2016/01/08 Javascript
基于BootStrap Metronic开发框架经验小结【六】对话框及提示框的处理和优化
2016/05/12 Javascript
jQuery实现立体式数字滚动条增加效果
2016/12/21 Javascript
jQuery中Chosen三级联动功能实例代码
2017/03/07 Javascript
javascript使用btoa和atob来进行Base64转码和解码
2017/03/20 Javascript
Vue SSR 组件加载问题
2018/05/02 Javascript
小程序异步问题之多个网络请求依次执行并依次收集请求结果
2019/05/05 Javascript
js中调用微信的扫描二维码功能的实现代码
2020/04/11 Javascript
[01:02:38]DOTA2-DPC中国联赛定级赛 LBZS vs Phoenix BO3第二场 1月10日
2021/03/11 DOTA
寻找网站后台地址的python脚本
2014/09/01 Python
讲解Python中运算符使用时的优先级
2015/05/14 Python
python修改list中所有元素类型的三种方法
2018/04/09 Python
Django框架使用mysql视图操作示例
2019/05/15 Python
python程序 创建多线程过程详解
2019/09/23 Python
win7下 python3.6 安装opencv 和 opencv-contrib-python解决 cv2.xfeatures2d.SIFT_create() 的问题
2019/10/24 Python
详细分析Python垃圾回收机制
2020/07/01 Python
python爬虫请求头的使用
2020/12/01 Python
美国五金商店:Ace Hardware
2018/03/27 全球购物
轻松制作精彩视频:Animoto
2018/09/19 全球购物
高中军训感想300字
2014/03/04 职场文书
2014年办公室文秘工作总结
2014/12/09 职场文书
北京爱情故事观后感
2015/06/12 职场文书
民间借贷纠纷答辩状
2015/08/03 职场文书