Search code examples
angularkendo-uicomponentsangular6kendo-window

Angular6 open/show component by service


I built an angular component to use as a dialog for my app (e.g to show application errors) and a dialog-service to open/show that dialog from other components.

dialog.component.html

<kendo-dialog *ngIf="opened">
  <div>
    Some Content
  </div>
</kendo-dialog>

dialog.compontent.ts

import { Component, OnInit } from '@angular/core';
import { Dialog } from './dialog'; // Model

@Component({
  selector: 'dialog',
  templateUrl: './dialog.component.html',
  styleUrls: ['./dialog.component.scss']
})
export class DialogComponent implements OnInit {
  public opened = false;
  public dialog: Dialog; // Contains properties like title, message

  constructor() {
  }

  ngOnInit() {}

  public showDialog(dialog: Dialog) {
    this.dialog = dialog;
    this.opened = true;
  }
}

dialog.service.ts

import { Injectable } from '@angular/core';
import { Dialog } from './dialog';

@Injectable()
export class DialogService {
  constructor() {}

  public showDialog(
    title: string,
    message: string,
    isConfirm: boolean,
    icon?: string
  ) {
    const dialog = new Dialog(title, message, isConfirm, icon);

    // TODO: Open/Show Dialog Component with DialogService
    // set opened property from DialogComponent = true
  }
}

Whats do I need to do in DialogService to be able showing my DialogComponent from anywhere? For example I have a try/catch block somewhere and want to show the error message with DialogComponent:

try {
// Do something
} catch(error => {
    this.dialogService.showDialog('Title', error.Message, true);
})

Solution

  • Your should use the Angular CDK Overlay.

    It allows you to create a backdrop with a certain opacity, to dynamically inject a component over it, and to configure the position strategy and scroll strategy.

    Let me provide you some code that may help you get started:

    constructor(
       private overlay: Overlay,
       private componentFactoryResolver: ComponentFactoryResolver
    ) {}
    
    let componentFactory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
    
    const overlayRef = this.overlay.create(
      {
        hasBackdrop: true,
        positionStrategy: this.overlay.position().global().centerHorizontally().centerVertically()
      }
    );
    
    overlayRef.backdropClick().subscribe(res => {
      overlayRef.detach();
    });
    
    let portal = new ComponentPortal(componentFactory.componentType);
    
    let component = overlayRef.attach<DialogComponent>(portal);
    
    component.instance.onCloseClick.subscribe(() => {
      overlayRef.detach();
    });