Search code examples
angularmodal-dialogangular2-servicesangular2-components

Angular2 modal dialog


Structure of the app:

AppService AppComponent -> HeroComponent -> WeaponComponent -> ButtonComponent

When someone clicks on the button (ButtonComponent), I would like to open a modal dialog in the AppComponent.

The best way I can think of is making a dialogObservable in the AppService. The ButtonComponent sets the observable and the AppComponent listens to it, and shows the dialog when there is a dialog set.

This already feels a bit messy.

But to make it worse, I also need buttons in the Dialog. When someone clicks on the "OK" button, I want to call an action from the WeaponComponent. Which is impossible, as far as I know. So what do I do? Create another observable in the service, and listen to it in the WeaponComponent.

This feels very messy, and I feel there must be a better way. I just can't figure it out.


Solution

  • I had a similar problem and I solved it by adding a modal in my root module component, and providing a ModalService accross my app.

    ModalService is used as an event dispatcher, to dispatch the modal event.

    Exemple with just signatures (to be easy to understand, implementation is not that hard):

    @Injectable()
    export class ModalService{
        public registerModal(name:string, onPop:()=>void):void;
        public popModal(name:string):void;
    }
    

    This way your ModalComponent can be anywhere (and you can have a lot of modals with different names) and you can pop it from anywhere since you just need to get the ModalService.

    Note that to make this work, you have to use only one instance of ModalService, so it has to be declared in your module.forRoot() method.

    EDIT:

    To fix the context issue, you can declare your function and store it in a variable, this way:

    function foo():any{
    }
    

    becomes

    foo=():any => {
    }
    

    then you can pass the callback method to your modal using this.foo, it will not loose the context.