详解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 相关文章推荐
线路分流自动跳转代码;希望对大家有用!
Dec 02 Javascript
AJAX异步从优酷专辑中采集所有视频及信息(JavaScript代码)
Nov 20 Javascript
深入探讨javascript函数式编程
Oct 11 Javascript
浅谈toLowerCase和toLocaleLowerCase的区别
Aug 15 Javascript
Vue.js实现多条件筛选、搜索、排序及分页的表格功能
Nov 24 Javascript
jQuery插件FusionCharts实现的MSBar3D图效果示例【附demo源码】
Mar 23 jQuery
iview日期控件,双向绑定日期格式的方法
Mar 15 Javascript
node实现登录图片验证码的示例代码
Apr 20 Javascript
js实现二级菜单点击显示当前内容效果
Apr 28 Javascript
JS module的导出和导入的实现代码
Feb 25 Javascript
layui(1.0.9)文件上传upload,前后端的实例代码
Sep 26 Javascript
react实现移动端下拉菜单的示例代码
Jan 16 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
探讨fckeditor在Php中的配置详解
2013/06/08 PHP
PHP判断指定时间段的2个方法
2014/03/14 PHP
PHP采集类snoopy详细介绍(snoopy使用教程)
2014/06/19 PHP
简介PHP的Yii框架中缓存的一些高级用法
2016/03/29 PHP
详解PHP使用Redis存储session时的一个Warning定位
2017/07/05 PHP
PHP 传输会话curl函数的实例详解
2017/09/12 PHP
IE 下的只读 innerHTML
2009/08/21 Javascript
理解JavaScript的prototype属性
2012/02/11 Javascript
jQuery Mobile的loading对话框显示/隐藏方法分享
2013/11/26 Javascript
jquery中$each()方法的使用指南
2015/04/30 Javascript
ECMA5数组的新增方法有哪些及forEach()模仿实现
2015/11/03 Javascript
JavaScript实现实时更新系统时间的实例代码
2017/04/04 Javascript
JS实现评价的星星功能
2017/08/20 Javascript
浅析vue-router原理
2018/10/19 Javascript
python通过openpyxl生成Excel文件的方法
2015/05/12 Python
python开发之str.format()用法实例分析
2016/02/22 Python
Python 批量合并多个txt文件的实例讲解
2018/05/08 Python
python selenium 对浏览器标签页进行关闭和切换的方法
2018/05/21 Python
python 多线程串行和并行的实例
2019/02/22 Python
Python中asyncio模块的深入讲解
2019/06/10 Python
Django url,从一个页面调到另个页面的方法
2019/08/21 Python
tensorflow之获取tensor的shape作为max_pool的ksize实例
2020/01/04 Python
Python图片处理模块PIL操作方法(pillow)
2020/04/07 Python
加拿大在线眼镜零售商:SmartBuyGlasses加拿大
2019/05/25 全球购物
Booking.com缤客中国:全球酒店在线预订网站
2020/05/03 全球购物
一份软件工程师的面试试题
2016/02/01 面试题
音乐表演专业毕业生求职信
2013/10/14 职场文书
逃课上网检讨书
2014/02/20 职场文书
医德医风演讲稿
2014/05/20 职场文书
酒店管理毕业生自荐信
2014/05/25 职场文书
三好生演讲稿
2014/09/12 职场文书
张家口市高新区党工委群众路线教育实践活动整改方案
2014/10/25 职场文书
工人先锋号事迹材料
2014/12/24 职场文书
药品开票员岗位职责
2015/04/15 职场文书
2016继续教育研修日志
2015/11/13 职场文书
2019数学教师下学期工作总结
2019/06/27 职场文书