¿Alguien puede proporcionar un ejemplo de cómo cargar dinámicamente un componente en un Material MatDialog?
Lo que me gustaría hacer es esto: proporcionaré los datos de configuración de MatDialog con un tipo de componente del que el cuadro de diálogo crearía una instancia y lo colocaría dentro de su área de contenido de cuadro de diálogo mat.
Parece que necesitaría usar alguna combinación de ng-template y viewContainerRef, pero no sé cómo instanciar el tipo de componente proporcionado e insertarlo en el área deseada.
Un ejemplo sencillo:
<h2 mat-dialog-title>MyTitle</h2> <mat-dialog-content> <---- dynamically loaded component would be inserted here ----> </mat-dialog-content> <mat-dialog-actions> <button mat-button mat-dialog-close>Cancel</button> <button mat-button [mat-dialog-close]="true">Save</button> </mat-dialog-actions>Hay diferentes opciones:
1) Directiva estructural integrada ngComponentOutlet
<ng-container *ngComponentOutlet="data.component"></ng-container> 2) Usando material angular cdk. Más precisamente, puede usar PortalModule desde el punto de entrada secundario @angular/cdk/portal
dialog.component.ts
import { ComponentPortal } from '@angular/cdk/portal'; @Component({...}) export class DialogDialog { portal: ComponentPortal<any>; constructor(... @Inject(MAT_DIALOG_DATA) public data: any) { } ngOnInit() { this.portal = new ComponentPortal(this.data.component); }diálogo.componente.html
<ng-template [cdkPortalOutlet]="portal"></ng-template>3) Uso de la API de bajo nivel de Angular
dialog.component.ts
@Component({...}) export class DialogDialog { @ViewChild('target', { read: ViewContainerRef }) vcRef: ViewContainerRef; componentRef: ComponentRef<any>; constructor( ... private resolver: ComponentFactoryResolver, @Inject(MAT_DIALOG_DATA) public data: any) { } ngOnInit() { const factory = this.resolver.resolveComponentFactory(this.data.component); this.componentRef = this.vcRef.createComponent(factory); } ngOnDestroy() { if (this.componentRef) { this.componentRef.destroy(); } } }diálogo.componente.html
<ng-template #target></ng-template>El componente modal real .ts: (tenga en cuenta que el html del componente modal es donde escribirá su código arriba)
import {Component, Inject, OnInit} from '@angular/core'; import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material'; @Component({ selector: 'app-modal', templateUrl: './modal.component.html', styleUrls: ['./modal.component.css'] }) export class ModalComponent implements OnInit { constructor(public dialogRef: MatDialogRef<CreateFirmComponent>, @Inject(MAT_DIALOG_DATA) public data: any) { } ngOnInit() { } onConfirm() { this.dialogRef.close(true); } onCancel(): void { this.dialogRef.close(false); } }Y el componente desde donde llamas al Modal:
import {Component, OnInit} from '@angular/core'; import {MatDialog} from '@angular/material'; import {ModalComponent} from './modal-component'; @Component({ selector: 'app-list', templateUrl: './list.component.html', styleUrls: ['./list.component.css'] }) export class ListComponent implements OnInit { constructor(public dialog: MatDialog) { } openDialog(): void { let dialogRef = this.dialog.open(ModalComponent, { width: '500px' }); dialogRef.afterClosed().subscribe(result => { // result is what you get after you close the Modal }); } }