简体   繁体   中英

angular2 : open ng2-bootstrap modal from parent component

I'm trying to open an ng2-bootstrap modal from a parent component. I have created a ModalComponent and I "exportAs: child". My ModalComponent looks like

import { Component, Input, ViewChild } from '@angular/core';
import { ModalDirective } from 'ng2-bootstrap/ng2-bootstrap';

@Component({
    selector: 'modal',
    moduleId: module.id,
    templateUrl: 'modal.component.html',
    styleUrls: ['modal.component.css'],
    exportAs: 'child'
})
export class ModalComponent {

    @ViewChild('childModal') public childModal:ModalDirective;

    public show( variant ):void {

        console.log( this.childModal );
        this.childModal.show();
    }

    public hide():void {

        this.childModal.hide();
    }
}

and I include the modal in the parent template as

<modal #c="child"></modal>

... and call it from the parent template as

<button type="button" class="btn btn-primary" (click)="c.show(variant)">open</button>

I hit the "show" method inside the ModalComponent correctly but the value of "childModal" is always undefined (Nb: console.log() statement).

Any pointers are greatly appreciated.

In my view an API for modals that requires you to go through components and query modal instance is far from being optimal. A much better approach is to have a modal as service. This way you can call open method on a modal from any place of your code (including services, ex.: login service).

This is exactly why the API for modals is modeled as service in the https://ng-bootstrap.github.io/#/components/modal . By using it you can invoke a modal from any place by simply doing modalService.open(....) .

BTW, the service-based approach to modals is also present in other Angular2 widget libraries (ex. material design).

In short: re-consider APIs you are using.

With the assistance of @yurzui I realised my mistake was in the HTML. I had defined my modal as

<div bsModal #smModal="bs-modal"...

Nb: "smModal" which needed to be rewritten as

<div bsModal #childModal="bs-modal"...

... and voila! "childModal" is no longer undefined.

Try this

component.ts file should be as follows

import { Component, TemplateRef } from '@angular/core';
import { BsModalService, BsModalRef } from 'ngx-bootstrap/modal';
 
@Component({
  selector: 'demo-modal-service-static',
  templateUrl: './service-template.html'
})
export class DemoModalServiceStaticComponent {
  modalRef: BsModalRef;
  constructor(private modalService: BsModalService) {}
 
  openModal(template: TemplateRef<any>) {
    this.modalRef = this.modalService.show(template);
  }
}

html should be

<button type="button" class="btn btn-primary" (click)="openModal(template)">Create template modal</button>
 
<ng-template #template>
  <div class="modal-header">
    <h4 class="modal-title pull-left">Modal</h4>
    <button type="button" class="close pull-right" aria-label="Close" (click)="modalRef.hide()">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    This is a modal.
  </div>
</ng-template>

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