详解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滚动条插件源码
Mar 03 Javascript
js淡入淡出焦点图幻灯片效果代码分享
Sep 08 Javascript
javascript同步服务器时间和同步倒计时小技巧
Sep 24 Javascript
利用JS生成博文目录及CSS定制博客
Feb 10 Javascript
javascript正则表达式中分组详解
Jul 17 Javascript
利用jQuery异步上传文件的插件用法详解
Jul 19 jQuery
BootStrap Fileinput插件和Bootstrap table表格插件相结合实现文件上传、预览、提交的导入Excel数据操作步骤
Aug 07 Javascript
jQuery 防止相同的事件快速重复触发方法
Feb 08 jQuery
详解Node.js中的Async和Await函数
Feb 22 Javascript
vue语法自动转typescript(解放双手)
Sep 18 Javascript
JS面向对象编程基础篇(三) 继承操作实例详解
Mar 03 Javascript
使用vue引入maptalks地图及聚合效果的实现
Aug 10 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实现的简单数据库操作Model类
2016/11/16 PHP
写了一个layout,拖动条连贯,内容区可为iframe
2007/08/19 Javascript
JavaScript 嵌套函数指向this对象错误的解决方法
2010/03/15 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
2013/10/24 Javascript
jQuery filter函数使用方法
2014/05/19 Javascript
javascript快速排序算法详解
2014/09/17 Javascript
node.js中的fs.exists方法使用说明
2014/12/17 Javascript
使用js画图之画切线
2015/01/12 Javascript
JavaScript数组随机排列实现随机洗牌功能
2015/03/19 Javascript
超实用的JavaScript表单代码段
2016/02/26 Javascript
jquery 无限极下拉菜单的简单实例(精简浓缩版)
2016/05/31 Javascript
jQuery实现的网格线绘制方法
2016/06/20 Javascript
JavaScript蒙板(model)功能的简单实现代码
2016/08/04 Javascript
老生常谈javascript中逻辑运算符&amp;&amp;和||的返回值问题
2017/04/13 Javascript
Angular 4依赖注入学习教程之FactoryProvider配置依赖对象(五)
2017/06/04 Javascript
详解javascript 变量提升(Hoisting)
2019/03/12 Javascript
JavaScript生成一个不重复的ID的方法示例
2019/09/16 Javascript
nodejs中的异步编程知识点详解
2021/01/17 NodeJs
[01:00:25]NB vs Secret 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
Python判断文本中消息重复次数的方法
2016/04/27 Python
理解Python中的绝对路径和相对路径
2017/08/30 Python
Python模块搜索路径代码详解
2018/01/29 Python
python3解析库pyquery的深入讲解
2018/06/26 Python
详解css3自定义滚动条样式写法
2017/12/25 HTML / CSS
花园仓库建筑:Garden Buildings Direct
2018/02/16 全球购物
欧舒丹俄罗斯官方网站:L’OCCITANE俄罗斯
2019/11/22 全球购物
意大利买卖二手奢侈品网站:LAMPOO
2020/06/03 全球购物
群众路线教育实践活动方案
2014/02/02 职场文书
户外活动总结范文
2014/04/30 职场文书
大学生村官座谈会发言材料
2014/05/25 职场文书
2015年转正工作总结范文
2015/04/02 职场文书
法律讲堂观后感
2015/06/11 职场文书
2016幼儿园新学期寄语
2015/12/03 职场文书
python实现MD5进行文件去重的示例代码
2021/07/09 Python
DQL数据查询语句使用示例
2022/12/24 MySQL
css弧边选项卡的项目实践
2023/05/07 HTML / CSS