4

I want to open or close modals from Another Module with the help of component 1. But currently I am unable to access the modalRef of ngBootstrap of the modals in that component so that I can close/open it.

Suppose this scenerio

One Module

<component1></component1>

Another Module this module have multiple components and each component have modal in it which I need to show or hide based on the conditions from component 1.

<component2> //have ng bootstrap modal in it </component2>
<component3> //have ng bootstrap modal in it </component3>
<component4> //have ng bootstrap modal in it </component4>
<component5> //have ng bootstrap modal in it </component5>
<component6> //have ng bootstrap modal in it </component6>

Currently I am doing this by just putting one hidden button in that module and the click it using the JavaScript from another component, I know that this is not a good approach so I want someone to give me some approach to calling these modals or tell me if there is anything to change in the design.

As far as I know I think service will be good to do this. But before changing the design I want someone opinion. Thanks

Mehmood Ahmad
  • 627
  • 2
  • 5
  • 22
  • Your description is quite vague, and doesn't make much sense (modules don't contain buttons). Post a complete minimal example, as a plunkr, reproducing the problem. – JB Nizet Oct 17 '17 at 14:16
  • you need to include `NgbModule` in to your other module as well so that it will ve available. – Aniruddha Das Oct 17 '17 at 14:18
  • Modules have no button actually its template have buttons. The question is quite simple in the above scenerio how can I open and close the modal from another module. Because currently I am unable to access the modalRef in that component to close it. Kindly tell me if you want more clarification. Thanks. – Mehmood Ahmad Oct 17 '17 at 14:25

5 Answers5

3

I just came across the same problem and found this thread, Aniruddha Das did a great job of highlighting the basic requirements but I found it missed the TemplateRef usage which is the next bit and just in case anyone else has this issue I'll finish it. using the same model as Aniruddha's

Template:

<ng-template #updatemodal>
  <div class="modal">
    stuff here...
  </div>
</ng-template>

Component:

@ViewChild('updatemodal')
private modalRef: TemplateRef<any>;

private myModal<any>;

constructor(SomeService: SomeService, modalService: NgbModal){
  this.SomeService.popup.subscribe((val)=>{
     if(val === 'open') {
       this.myModal = this.modalService.open(this.modalRef);
     }
   });
}

Referencing the modal that has been created is a great way to allow more use and flexibility within the response and by using:

this.myModal.result.then((result) =>{
      this.closeResult = `Closed with: ${result}`;
    }, (reason) => {
      this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
    });

from the NgBootstrap site

2

Create a service with Observable and trigger and emit which user click on the close button.

Once the close button clicked, the event can be catched in any other component and action can be performed.

Service

@Injectable()
export class SomeService {
   public popup: Subject<any> = new Subject<any>();

  constructor() {}
}

Component which have modal to close.

constructor(SomeService: SomeService){
  this.SomeService.popup.subscribe((val)=>{
     if(val === 'close') {
       // close the modal
     }
   });
}

And now from the other component, you can trigger the event to close the model. you can perform the close from any component.

constructor(private SomeService: SomeService) {}

SomeMethod() {
  this.someService.popup.next('close');
}
Mehmood Ahmad
  • 627
  • 2
  • 5
  • 22
Aniruddha Das
  • 20,520
  • 23
  • 96
  • 132
  • 1
    Please tell me that what is Subject in the example and how this service is pointing to modelRef of the modal in the components – Mehmood Ahmad Oct 17 '17 at 14:48
  • 1
    `Subject` or `BevavourSubject` are observable type variable available in angulr to trigger events which can be caught by any other event. you can follow this link to see more -- https://medium.com/@benlesh/on-the-subject-of-subjects-in-rxjs-2b08b7198b93 – Aniruddha Das Oct 17 '17 at 14:53
  • 1
    Thanks for your time. I thinks that this is the solution of my problem but my application grew big with this foolish hidden button approach. I will apply your solution on my app and if this solves the problem then I will accept it. – Mehmood Ahmad Oct 17 '17 at 14:57
  • 1
    sure, make sure to accept or up vote if it resolve your problem. – Aniruddha Das Oct 17 '17 at 15:00
  • Can you please elaborate the (//close the modal) comment. In short how this service is linked (or have references) to the modal in component so that I can open or close it. – Mehmood Ahmad Oct 18 '17 at 07:11
1
  1. In app.module.ts:

    {
        ...
        imports [...],
        entryComponents: [ModalComponent],
        ...
    }
    
  2. Write your model, as part "Components as content" from here.

  3. In the component where you use the modal:

    • import ModalComponent and dependencies
    • constructor(private modalService: NgbModal)
    • preferable put this into a method:

      const modal = this.modalService.open(ModalComponent);
      modal.componentInstance.title = "Dialog";
      modal.componentInstance.body = "Your message";
      
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Andy
  • 35
  • 3
0

The problem is the NgbModule is available to the module and not other module in your application. When when imports a module ( here NgbModule) it is specific to that module only. So either you have to include NgbModule in the other module or export that in the current module and import current module in the other module.

import it in the other module

@NgModule({
  imports: [
    NgbModule,
  ],

Or import the first module in the secound which already included the NgbModule module.

Aniruddha Das
  • 20,520
  • 23
  • 96
  • 132
-3

See this answer , you can create a custom modal without any external library: Angular 2.0 and Modal Dialog