Angular 2+ & ngBootstrap - Shared Modals

℡╲_俬逩灬. 提交于 2019-11-28 06:37:04

问题


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:


  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




回答2:


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.



来源:https://stackoverflow.com/questions/42633144/angular-2-ngbootstrap-shared-modals

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!