简体   繁体   中英

Angular 2+ & ngBootstrap - Shared Modals

Is it possible to have a ngBootstrap modal as a shared component and use an instance of it in other components.

I'd like to have one Modal that prompts the user to delete a record and I'd like to re-use it across multiple components with different record types.

ngBootstrap site shows a "Components As Content" example but in that example it looks like the ModalComponent dictates whether to open or close the ModalContents. I'd like the ability to open/close an instance of a modal from another (arbitrary) component.

Is this possible?

  1. Create a CommonModule as below,

     import { NgModule} from '@angular/core'; import { CommonModalComponent } from './modal.component'; import { ModalDirective,ModalModule } from 'ng2-bootstrap/ng2-bootstrap'; @NgModule({ imports:[ModalModule], declarations: [ CommonModalComponent ], exports:[CommonModalComponent] }) export class CommonModule {} 
  2. As you can see, CommonModalComponent is a declaration in CommonModule, Create that component as below,

     import {Component,Input, ViewChild} from '@angular/core'; import { ModalDirective } from 'ng2-bootstrap/ng2-bootstrap'; @Component({ selector: 'common-modal', template: ` <div bsModal #childModal="bs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true"> <div class="modal-dialog modal-sm"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title pull-left">{{title}}</h4> <button type="button" class="close pull-right" aria-label="Close" (click)="hideChildModal()"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body"> <ng-content select=".modal-body"> </ng-content> </div> <div class="modal-footer"> <div class="pull-left"> <button class="btn btn-default" (click)="hide()"> Cancel </button> </div> </div> </div> </div> </div> `, }) export class CommonModalComponent { @ViewChild('childModal') public childModal:ModalDirective; @Input() title?:string; constructor() { } show(){ this.childModal.show(); } hide(){ this.childModal.hide(); } } 
  3. Using the CommonModule and its components in the AppModule as below,

     import {Component, ViewChild, ViewContainerRef, NgModule} from '@angular/core'; import {BrowserModule} from '@angular/platform-browser'; import {CommonModule} from './common.module'; import {CommonModalComponent} './modal.component'; @Component({ selector: 'my-app', template: ` <div> <h2>Hello {{name}}</h2> <button type="button" class="btn btn-primary" (click)="childModal.show()">Open modal</button> <common-modal #childModal [title]="'common modal'"> </common-modal> </div> `, }) export class App { @ViewChild('childComponent') childComponent:CommonModalComponent; name:string; constructor(private viewContainerRef: ViewContainerRef) { this.name = 'Angular 2 Common Module with ModalComponent' } } @NgModule({ imports: [ BrowserModule,CommonModule ], declarations: [ App ], bootstrap: [ App ] }) export class AppModule {} 

LIVE DEMO

Additional Information :

  1. This common module can be used any where to reproduce your needs with the help of ContentProjection in Angular 2 which can be seen in below line

     <ng-content select=".modal-body"> </ng-content> 
  2. In your AppComponent, you can use this and add items to your CommonModal as,

     <div class="modal-body"> Some Form Controls or Displaying content </div> 

    This can be seen in this LIVE DEMO

  3. Since, you want modal for warning messages or confirmation you can reuse the common-modal and create another WarningModalComponent and use that across application

Well, per their documentation when you instantiate the modal, you get the NgbModalRef instance. This instance has a property of the componentInstance that is, obviously, the instance of the component your using for your modal content.

For that to work, the component instance has to be injected with ActiveModal instance in its constructor which can give you access to its methods that you can later use.

open() {
  const modalRef = this.modalService.open(NgbdModalContent);

  // you should have access to the activeModal methods like dismiss
  modalRef.componentInstance.activeModal.dismiss("some reason");
}

You can use this to create a shared service that will keep the reference to the modal and manipulate it from any component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM