欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Angular与模态框的通讯

程序员文章站 2022-07-02 14:26:29
...

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,感觉好像有点猫腻。我们看一下效果图就知道了。

Angular与模态框的通讯

我们会发现,这个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>

至此我们实现的只是数据从父组件到弹框的单向传递,我们来看一下效果。

Angular与模态框的通讯

三、弹框数据返传给父组件

那么反过来呢?弹框的数据要怎么传递给它的父组件,我们再来深究一下弹框里面的代码。

在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是什么东西。

Angular与模态框的通讯

我们发现原来的isConfirmed是true,现在开始赋值为字符串“测试”。在修改result之前还要将DialogComponent<ConfirmModel, boolean>修改为DialogComponent<ConfirmModel, any>,正如上面所讲,result是一个boolean类型,这一点取决于{DialogComponent<ConfirmModel, boolean>}。修改之后再审查一下。

Angular与模态框的通讯

我们发现变成测试了,这时候我们就知道了,弹框里面的数据要返传给父组件,可以通过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