详解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 相关文章推荐
表格 隔行换色升级版
Nov 07 Javascript
Jquery下attr和removeAttr的使用方法
Dec 28 Javascript
AMD异步模块定义介绍和Require.js中使用jQuery及jQuery插件的方法
Jun 06 Javascript
jquery获取选中的文本和值的方法
Jul 08 Javascript
js弹出对话框方式小结
Nov 17 Javascript
jquery实现简单的瀑布流布局
Dec 11 Javascript
EasyUI Datebox 日期验证之开始日期小于结束时间
May 19 Javascript
JS 学习总结之正则表达式的懒惰性和贪婪性
Jul 03 Javascript
Vue调试神器vue-devtools安装方法
Dec 12 Javascript
vue中关闭eslint的方法分析
Aug 04 Javascript
vue2.0 element-ui中el-select选择器无法显示选中的内容(解决方法)
Aug 24 Javascript
vue中@change兼容问题详解
Oct 25 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的curl实现get和post的代码
2008/08/23 PHP
php数组总结篇(一)
2008/09/30 PHP
php 设计模式之 单例模式
2008/12/19 PHP
微信公众号开发之微信公共平台消息回复类实例
2014/11/14 PHP
php微信开发之带参数二维码的使用
2016/08/03 PHP
PHP实现用session来实现记录用户登陆信息
2018/10/15 PHP
Laravel框架集合用法实例浅析
2020/05/14 PHP
javascript+xml技术实现分页浏览
2008/07/27 Javascript
javascript权威指南 学习笔记之null和undefined
2011/09/25 Javascript
js 数组操作之pop,push,unshift,splice,shift
2014/01/29 Javascript
jQuery如何将选中的对象转化为原始的DOM对象
2014/06/09 Javascript
JS实现的打字机效果完整实例
2016/06/20 Javascript
JS使用对象的defineProperty进行变量监控操作示例
2019/02/02 Javascript
nodejs实现用户登录路由功能
2019/05/22 NodeJs
关于在LayUI中使用AJAX提交巨坑记录
2019/10/25 Javascript
在react项目中使用antd的form组件,动态设置input框的值
2020/10/24 Javascript
pyv8学习python和javascript变量进行交互
2013/12/04 Python
详解如何为eclipse安装合适版本的python插件pydev
2018/11/04 Python
django admin后台添加导出excel功能示例代码
2019/05/15 Python
Python实现K折交叉验证法的方法步骤
2019/07/11 Python
Python实现栈和队列的简单操作方法示例
2019/11/29 Python
python GUI库图形界面开发之PyQt5浏览器控件QWebEngineView详细使用方法
2020/02/26 Python
python爬虫开发之使用Python爬虫库requests多线程抓取猫眼电影TOP100实例
2020/03/10 Python
利用Python的folium包绘制城市道路图的实现示例
2020/08/24 Python
英国Zoro工具:手动工具,电动工具和个人防护用品
2016/11/02 全球购物
Ralph Lauren英国官方网站:Ralph Lauren UK
2018/04/03 全球购物
波兰珠宝品牌:YES
2019/08/09 全球购物
送给程序员的20个Java集合面试问题
2014/08/06 面试题
车间调度岗位职责
2013/11/30 职场文书
大四本科生的自我评价
2013/12/30 职场文书
个人求职信范文
2014/05/24 职场文书
淘宝客服工作职责
2014/07/11 职场文书
工作经常出错的检讨书
2014/09/13 职场文书
2015年社区卫生工作总结
2015/04/21 职场文书
大学开学感言
2015/08/01 职场文书
python中的plt.cm.Paired用法说明
2021/05/31 Python