详解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 FormatNumber函数实现方法
Dec 30 Javascript
JavaScript与DropDownList 区别分析
Jan 01 Javascript
jQuery学习笔记之jQuery的事件
Dec 22 Javascript
textarea中的手动换行处理的jquery代码
Feb 26 Javascript
javascript setTimeout和setInterval计时的区别详解
Jun 21 Javascript
jquery mobile动态添加元素之后不能正确渲染解决方法说明
Mar 05 Javascript
js实现鼠标滚轮控制图片缩放效果的方法
Feb 20 Javascript
Angularjs注入拦截器实现Loading效果
Dec 28 Javascript
理解javascript中的MVC模式
Jan 28 Javascript
node.js从数据库获取数据
May 08 Javascript
js实现文章目录索引导航(table of content)
May 10 Javascript
手写Vue源码之数据劫持示例详解
Jan 04 Vue.js
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+ajax实现的点击浏览量加1
2015/04/16 PHP
php实现word转html的方法
2016/01/22 PHP
PHP实现QQ快速登录的方法
2016/09/28 PHP
Prototype Date对象 学习
2009/07/12 Javascript
基于jquery的给文章加入关键字链接
2010/10/26 Javascript
js模仿html5 placeholder适应于不支持的浏览器
2013/01/13 Javascript
JS如何判断移动端访问设备并解析对应CSS
2013/11/27 Javascript
jQuery制作的别致导航有阴影背景高亮模式窗口
2014/04/15 Javascript
node.js中的fs.readFile方法使用说明
2014/12/15 Javascript
Js实现无刷新删除内容
2015/04/29 Javascript
原生js编写焦点图效果
2016/12/08 Javascript
微信小程序 本地数据存储实例详解
2017/04/13 Javascript
JavaScript 隐性类型转换步骤浅析
2018/03/15 Javascript
小程序开发基础之view视图容器
2018/08/21 Javascript
基于原生JS封装的Modal对话框插件的示例代码
2020/09/09 Javascript
如何利用JS将手机号中间四位变成*号
2020/09/29 Javascript
[07:55]2014DOTA2 TI正赛第三日 VG上演推进荣耀DKEG告别
2014/07/21 DOTA
Python实现优先级队列结构的方法详解
2016/06/02 Python
Python自定义主从分布式架构实例分析
2016/09/19 Python
python中类和实例如何绑定属性与方法示例详解
2017/08/18 Python
pandas DataFrame创建方法的方式
2019/08/02 Python
Python字典添加,删除,查询等相关操作方法详解
2020/02/07 Python
keras自定义损失函数并且模型加载的写法介绍
2020/06/15 Python
Python bisect模块原理及常见实例
2020/06/17 Python
如何用python免费看美剧
2020/08/11 Python
Python 使用Opencv实现目标检测与识别的示例代码
2020/09/08 Python
大学生自我鉴定
2013/12/08 职场文书
主办会计岗位职责
2014/03/13 职场文书
2014年大学生就业规划书
2014/04/04 职场文书
机关党员进社区活动总结
2014/07/05 职场文书
施工安全责任书范本
2014/07/24 职场文书
六一儿童节开幕词
2015/01/29 职场文书
2015年保育员个人工作总结
2015/05/13 职场文书
高考满分作文赏析(2篇)
2019/08/12 职场文书
Redis+Lua脚本实现计数器接口防刷功能(升级版)
2022/02/12 Redis
Win10开机修复磁盘错误怎么跳过?Win10关闭开机磁盘检查的方法
2022/09/23 数码科技