Manuela
Manuela

Reputation: 137

Angular: Show Component within Popup

I have a PopupComponent (within a Angular Library) with some Input variables that I'm using like this:

<lib-popup
    [popupHeight] = "popupHeight"
    [popupWidth] = "popupWidth"
    [popupPositionX] = "popupPositionX"
    [popupPositionY] = "popupPositionY"
  >
</lib-popup>

Now I want to insert for example my MapComponent into that Popup, so that when I open the popup, it shows a Map.

I added another input variable contentComponent like this:

  <lib-popup
    [popupHeight] = "popupHeight"
    [popupWidth] = "popupWidth"
    [popupPositionX] = "popupPositionX"
    [popupPositionY] = "popupPositionY"
    [contentComponent] = "GeomapComponent"
  >
  </lib-popup>

My popup.component.ts looks like this:

import { Component, Input, OnInit } from '@angular/core';
import { MatDialog, MatDialogConfig } from '@angular/material';
import { PopupContentDefaultComponent } from './popup.content.default.component';

@Component({
  selector: 'lib-popup',
  templateUrl: './popup.component.html',
  styleUrls: ['./popup.component.css']
})
export class PopupComponent implements OnInit {

  @Input() popupPositionX = ''; // use default (px)
  @Input() popupPositionY = ''; // use default (px)
  @Input() popupHeight = '400px';
  @Input() popupWidth = '600px';
  @Input() popupOpen = false;
  @Input() popupClose = false;
  @Input() contentComponent = PopupContentDefaultComponent;

  private dialogRef!: any;
  private dialogConfig = new MatDialogConfig();

  constructor(public dialog: MatDialog) {}

  ngOnInit() {
    // set config values for popup
    this.dialogConfig.height = this.popupHeight;
    this.dialogConfig.width = this.popupWidth;
    this.dialogConfig.position = {
      left: this.popupPositionX,
      top: this.popupPositionY
    };

    if (this.popupOpen) {
      this.openDialog();
    }

    if (this.popupClose) {
      this.closeDialog();
    }
  }

  openDialog(): void {
    this.dialogRef = this.dialog.open(this.contentComponent, this.dialogConfig);
    console.log('Popup has been opened.');
  }

  closeDialog(): void {
    if (this.dialogRef) {
      this.dialogRef.close();
      console.log('Popup has been closed.');
    } else {
      console.log('There is no popup to close.');
    }
  }

}

Until now, everything works just fine! A popup will open which contains my MapComponent.

Now the problem:

I want to add a close button to my popup which is always there, no matter which content component I insert into the popup. So I think I need an additional component, something like PopupContentComponent which holds the button and some other stuff that each popup should contain, and which also has a placeholder for the component that I want to show.

But how do I do this in Angular?

I don't want to change the MapComponent and the Popup Component should stay within my library.

Upvotes: 1

Views: 7021

Answers (1)

ashish.gd
ashish.gd

Reputation: 1778

Your PopupComponent relies on MatDialog to show the pop-up with the component reference passed to it as contentComponent input binding.

MatDialog is merely a portal container and does not have its own body. Hence as you rightly said, you will need to create a PopupContentComponent which will have the default controls like the close button.

The PopupContentComponent can always project the passed in component Eg. MapComponent using ng-content.

This way your PopupComponent (using MatDialog) will always show PopupContentComponent which displays the required default controls and the child component (eg.MapComponent) using ng-content.

Also, you would be required to add the PopupContentComponent to your modules list of entryComponents.

Upvotes: 3

Related Questions