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












猜你喜欢

转载自blog.csdn.net/qq_34551390/article/details/78405367