Angular与模态框的通讯
Angular做项目的时候,难免会用到弹框(即模态框),如果模态框里面有一张表格,表格里面的数据需要从父组件(这里暂且先说成父组件吧!)里面获取,模态框的表格里面的数据经过修改,又传回给父组件,这种通讯方式该怎么实现?我们先来看一下最基本的自定义弹框代码,看看有没有什么突破口。
一、基本的自定义弹框代码
1.demo目录
----------app.component.ts
----------app.component.html
----------app.module.ts
----------confirm(文件夹)
------------confirm.component.ts
------------confirm.component.html
2.项目代码
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { CommonModule } from "@angular/common";
import { BootstrapModalModule } from 'ngx-bootstrap-modal';
import { AppComponent } from './app.component';
import { ConfirmComponent } from './confirm/confirm.component';
@NgModule({
declarations: [
AppComponent,
ConfirmComponent
],
imports: [
CommonModule,
BrowserModule,
BootstrapModalModule
],
providers: [],
bootstrap: [AppComponent],
entryComponents: [
ConfirmComponent
]
})
export class AppModule { }
app.component.ts
import { Component } from '@angular/core';
import { ConfirmComponent } from './confirm/confirm.component';
import { DialogService } from "ngx-bootstrap-modal";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
constructor(private dialogService:DialogService) {}
showConfirm() {
this.dialogService.addDialog(ConfirmComponent, {
title:'Confirm title',
message:'Confirm message'})
.subscribe((isConfirmed)=>{
if(isConfirmed) {}
else {}
});
}
}
app.component.html
<button type="button" class="btn btn-primary" (click)="showConfirm()">弹框</button>
confirm.component.ts
import { Component } from '@angular/core';
import { DialogComponent, DialogService } from "ngx-bootstrap-modal";
export interface ConfirmModel {
title:string;
message:string;
}
@Component({
selector: 'confirm',
templateUrl: './confirm.component.html',
styleUrls: ['./confirm.component.css']
})
export class ConfirmComponent extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
title: string;
message: string;
// 构造函数需要一个DialogService参数
constructor(dialogService: DialogService) {
super(dialogService);
}
confirm() {
// result是一个boolean类型,这一点取决于{DialogComponent<ConfirmModel, boolean>}
this.result = true;
// close() 方法是由 `DialogComponent` 定义的,用于关闭模态框。在HTML模板中也有可以调用。
this.close();
}
}
confirm.component.html
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" (click)="close()" >×</button>
<h4 class="modal-title">{{title}}</h4>
</div>
<div class="modal-body">
<p>{{message}}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" (click)="confirm()">OK</button>
<button type="button" class="btn btn-default" (click)="close()" >Cancel</button>
</div>
</div>
</div>
3.分析
我们来看一下app.component.ts和confirm.component.ts里面的title和message,感觉好像有点猫腻。我们看一下效果图就知道了。
我们会发现,这个Confirm title和Confirm message不就是通过app.component.ts里面的title和message传进去的嘛?那这就好办了,至少可以证明,父组件的数据可以传到弹框里面。那么我们再修改一下这个项目,让它实现父组件表格里面的数据传递到弹框里面并且把它渲染出来。
二、父组件数据传递到弹框
1.demo目录(项目目录不变)
2.项目代码
app.component.ts
import { Component } from '@angular/core';
import { ConfirmComponent } from './confirm/confirm.component';
import { DialogService } from "ngx-bootstrap-modal";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
datas=[//父组件里面的数据
{
name:"Mr.Chen",
id:1001
},
{
name:"Miss.Lee",
id:1003
},
{
name:"Mr.Fang",
id:1006
},
{
name:"Miss.Lin",
id:1009
}
]
constructor(private dialogService:DialogService) {}
showConfirm() {
this.dialogService.addDialog(ConfirmComponent, {
title:'Confirm title',
message: this.datas//传递给弹框
})
.subscribe((isConfirmed)=>{
if(isConfirmed) {}
else {}
});
}
}
app.component.html(在父组件渲染)
<button type="button" class="btn btn-primary" (click)="showConfirm()">弹框</button>
<table class="table">
<tr>
<th>编号</th>
<th>姓名</th>
<th>学号</th>
</tr>
<tr *ngFor="let data of datas;let i=index">
<td>{{i 1}}</td>
<td>{{data.name}}</td>
<td>{{data.id}}</td>
</tr>
</table>
confirm.component.ts
import { Component,OnInit } from '@angular/core';
import { DialogComponent, DialogService } from "ngx-bootstrap-modal";
export interface ConfirmModel {
title:string;
message:any; //注意这里的接口类型要更改
}
@Component({
selector: 'confirm',
templateUrl: './confirm.component.html',
styleUrls: ['./confirm.component.css']
})
export class ConfirmComponent extends DialogComponent<ConfirmModel, boolean> implements ConfirmModel {
title: string;
message: any;//这里的类型也要更改
ArrayData:any;
ngOnInit(){
this.ArrayData=this.message;//将父组件传递过来的值赋值给新的变量
}
// 构造函数需要一个DialogService参数
constructor(dialogService: DialogService) {
super(dialogService);
}
confirm() {
// result是一个boolean类型,这一点取决于{DialogComponent<ConfirmModel, boolean>}
this.result = true;
// close() 方法是由 `DialogComponent` 定义的,用于关闭模态框。在HTML模板中也有可以调用。
this.close();
}
}
confirm.component.html(在弹框中渲染)
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" (click)="close()" >×</button>
<h4 class="modal-title">{{title}}</h4>
</div>
<div class="modal-body">
<table class="table">
<tr>
<th>编号</th>
<th>姓名</th>
<th>学号</th>
</tr>
<tr *ngFor="let Data of ArrayData;let i=index">
<td>{{i 1}}</td>
<td>{{Data.name}}</td>
<td>{{Data.id}}</td>
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" (click)="confirm()">OK</button>
<button type="button" class="btn btn-default" (click)="close()" >Cancel</button>
</div>
</div>
</div>
至此我们实现的只是数据从父组件到弹框的单向传递,我们来看一下效果。
三、弹框数据返传给父组件
那么反过来呢?弹框的数据要怎么传递给它的父组件,我们再来深究一下弹框里面的代码。
在app.component.ts里面,有一个判断语句if(isConfirmed) {}如果弹框关闭,那么isConfirmed为true,进而执行if语句里面的代码。等等,为什么点击关闭按钮之后,isConfirmed会是true呢?我们再看看关闭按钮点击之后执行的函数
confirm() {
// result是一个boolean类型,这一点取决于{DialogComponent<ConfirmModel, boolean>}
this.result = true;
// close() 方法是由 `DialogComponent` 定义的,用于关闭模态框。在HTML模板中也有可以调用。
this.close();
}
也就是这个confirm方法,我们看到里面有一句this.result = true;会不会是它捣的鬼。我们把this.result赋值一个字符串,然后审查一下isConfirmed有没有改变。
在这之前我们先来确认一下原来的isConfirmed是什么东西。
我们发现原来的isConfirmed是true,现在开始赋值为字符串“测试”。在修改result之前还要将DialogComponent<ConfirmModel, boolean>修改为DialogComponent<ConfirmModel, any>,正如上面所讲,result是一个boolean类型,这一点取决于{DialogComponent<ConfirmModel, boolean>}。修改之后再审查一下。
我们发现变成测试了,这时候我们就知道了,弹框里面的数据要返传给父组件,可以通过result,传递什么类型, 就在{DialogComponent<ConfirmModel, boolean>}做相应的类型修改。当result有赋值,即存在的时候,在app.component.ts就执行if里面的语句,如果不存在,或者为false,就执行else里面的语句。
四、注意
在使用该弹框的时候,有一个版本问题,如果不做任何修改,在app.module.ts导入BootstrapModalModule的时候会出现下面的错误:
Metadata version mismatch for module C:/Users/ASUS/Desktop/angular/App/node_modules/ngx-bootstrap-modal/index.d.ts, found version 4,expected 3, resolving
symbol AppModulein C:/Users/ASUS/Desktop/angular/App/src/app/app.module.ts, resolving symbol AppModule
in C:/Users/ASUS/Desktop/angular/App/src/app/app.module.ts
这个错误只是版本的问题,尝试一下在package.json文件里面用"ngx-bootstrap-modal": "1.0.12"这个版本,就可以了。
详细的弹框使用可以查看http://blog.csdn.net/qq_34551390/article/details/78270869
更多专业前端知识,请上【猿2048】www.mk2048.com
上一篇: 基于layer插件的小实例:弹框图片