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