4

I'm new with Angular and I have some doubts about Modals with ng-Bootstrap. I've been able to open Modals that are in the same component and they work fine, an example is this one:

Link:

<a (click)="openAbout(contentAbout)" class="nav-link">About</a>

Click event:

  openAbout(contentAbout) {
    this.modalService.open(contentAbout, { centered: true, scrollable: true });
  }

Modal:

<ng-template #contentAbout let-c="close" let-d="dismiss">
  <div class="modal-header">
      <h4 class="modal-title" id="modal-primary-title">About us</h4>
      <button type="button" class="close" aria-label="Close" (click)="d('Cross click')">
        <span aria-hidden="true">&times;</span>
      </button>
  </div>
  <div class="modal-body centered">
    <h2>Gravity Now!</h2>
    <p>It is a platform designed for Space Apps Challenge and the Challenge Gravity Map, Earth Watch category and was chosen in the Top 5 of The Most Inspiring Projects of 2014.</p>
    <a href="https://2014.spaceappschallenge.org/awards/#globalawards" target="_blank">
      <img id="spaceLogo" src="./assets/space_apps.png">
    </a>
    <br>
    <img id="supernovaLogo" src="./assets/supernova-logo.png">
    <p>Also, you can download our apps.</p>
    <div class="row">
      <div class="col">
        <a href="https://play.google.com/store/apps/details?id=tk.supernova.gnow" target="_blank">
          <img class="logo" src="./assets/android.png">
        </a>
      </div>
      <div class="col">
        <a href="https://www.microsoft.com/en-us/p/gravity-now/9nblgggzjlp5" target="_blank">
          <img class="logoWindows" src="./assets/windows.png">
        </a>
      </div>
    </div>
  </div>
</ng-template>

And it works, however, I'd like to move this modal to a child component because I have 4 Modals and the code looks somehow disorganized, but if I create a new child component, move the modal code to the child and then, I add it to the parent component like this:

<app-about></app-about>

Nothing happens, since the click doesn't open anything. Does anyone have experience something similar? Do you know what should I change in the click event?

I read even the documentation and I cannot find an example related to my one:

https://ng-bootstrap.github.io/#/components/modal/examples

Thanks for any idea.

Federico Navarrete
  • 3,069
  • 5
  • 41
  • 76

3 Answers3

5

There are a couple of changes to take in consideration.

The first step is to register your Modals in the entryComponents section of your app.module.ts:

entryComponents: [
    AboutComponent,
],

Next, copy your old Modal to your new component and remove these 2 lines:

<ng-template #contentAbout let-c="close" let-d="dismiss">
</ng-template>

After, there is a small change in the logic of the click event on how to call it:

This is the new HTML code:

<a class="nav-link" (click)="openAbout()">About</a>

This is the new TypeScript event:

openAbout() {
    //Here you define the name of your component
    this.modalService.open(AboutComponent);
    //This section is if you want to have any variable to initialize
    //compConst.componentInstance.weight = undefined;
}

Also, in your new Component, you need to add change your constructor and add an instance of NgbActiveModal.

constructor(public activeModal: NgbActiveModal) { }

Another important change is in the logic of closing the modal, it needs to be changed to this:

<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
    <span aria-hidden="true">&times;</span>
</button>

You need to change the old: (click)="d('Cross click')" to (click)="activeModal.dismiss('Cross click')"

And with all these changes it will work like charm. I got some inspiration from here:

https://stackblitz.com/edit/angular-uwtgs6

Federico Navarrete
  • 3,069
  • 5
  • 41
  • 76
0

I haven't tried this but what you can do is that you can emit an event from child to parent. Try looking out for event emitter in the Angular docs.

Sagar Khatri
  • 575
  • 3
  • 16
0
Instead of calling child component in parent view you sould try this.
// if want to pass any value to child (parameter @Input() value in child);
// get back response from child (result @Output() EventEmitter value in child)
openChildComponentModel() {
        const modalRef = this.modalService.open(
            AboutComponent,
            {backdrop: 'static'}
        );
        modalRef.componentInstance.parameter= 'Text';
        modalRef.componentInstance.result.subscribe((response) => {}
        });
    }