详解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的动态创建DOM元素的代码
Dec 28 Javascript
JavaScript插入动态样式实现代码
Feb 22 Javascript
浅析jquery ajax异步调用方法中不能给全局变量赋值的原因及解决方法
Jan 10 Javascript
js中定义一个变量并判断其是否为空的方法
May 13 Javascript
iframe里的页面禁止右键事件的方法
Jun 10 Javascript
Jquery Mobile 自定义按钮图标
Nov 18 Javascript
ichart.js绘制虚线、平均分虚线效果的实现代码
May 05 Javascript
JavaScript中最容易混淆的作用域、提升、闭包知识详解(推荐)
Sep 05 Javascript
Node.JS中事件轮询(Event Loop)的解析
Feb 25 Javascript
基于node.js之调试器详解
Aug 22 Javascript
实现div滚动条默认最底部以及默认最右边的示例代码
Nov 15 Javascript
解决 viewer.js 动态更新图片导致无法预览的问题
May 14 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 编写的 25个游戏脚本
2009/05/11 PHP
IP138 IP地址查询小偷实现代码
2010/02/15 PHP
PHP代码优化技巧小结
2015/09/29 PHP
Redis在Laravel项目中的应用实例详解
2017/08/11 PHP
javascript 拖放效果实现代码
2010/01/22 Javascript
js 输出内容到新窗口具体实现代码
2013/05/31 Javascript
JavaScript全排列的六种算法 具体实现
2013/06/29 Javascript
两个数组去重的JS代码
2013/12/04 Javascript
jquery uploadify 在FF下无效的解决办法
2014/09/26 Javascript
jQuery中nextAll()方法用法实例
2015/01/07 Javascript
JavaScript输出当前时间Unix时间戳的方法
2015/04/06 Javascript
jquery实现向下滑出的二级导航下滑菜单效果
2015/08/25 Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
2016/01/15 Javascript
Express URL跳转(重定向)的实现方法
2017/04/07 Javascript
vue中实现图片和文件上传的示例代码
2018/03/16 Javascript
JS实现面向对象继承的5种方式分析
2018/07/21 Javascript
react的滑动图片验证码组件的示例代码
2019/02/27 Javascript
vue各种事件监听实例(小结)
2020/06/24 Javascript
Python中的ConfigParser模块使用详解
2015/05/04 Python
Selenium chrome配置代理Python版的方法
2018/11/29 Python
python石头剪刀布小游戏(三局两胜制)
2021/01/20 Python
对numpy下的轴交换transpose和swapaxes的示例解读
2019/06/26 Python
python的faker库用法
2019/11/28 Python
Python图像处理二值化方法实例汇总
2020/07/24 Python
基于python实现复制文件并重命名
2020/09/16 Python
python图片合成的示例
2020/11/09 Python
python基于selenium爬取斗鱼弹幕
2021/02/20 Python
巴西男士胡须和头发护理产品商店:Beard
2017/11/13 全球购物
期终自我鉴定
2014/02/17 职场文书
基层党员群众路线教育实践活动个人对照检查材料思想汇报
2014/10/05 职场文书
工作收入住址证明
2014/10/28 职场文书
2014年小学图书室工作总结
2014/12/09 职场文书
个人工作保证书
2015/02/28 职场文书
运动会加油稿30字
2015/07/21 职场文书
您对思维方式了解多少?
2019/12/09 职场文书
python基础之模块的导入
2021/10/24 Python