Angular与模态框的通讯

来源:互联网 发布:java web项目重新编译 编辑:程序博客网 时间:2024/06/05 16:55

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, resolvingsymbol AppModulein C:/Users/ASUS/Desktop/angular/App/src/app/app.module.ts, resolving symbol AppModulein 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












原创粉丝点击