Can anyone provide an example of how to dynamically load a component into a Material MatDialog?
What I would like to do is this: I will provide the MatDialog configuration data with a component Type which the dialog would then create an instance of and place inside it's mat-dialog-content area.
It appears I would need to use some combination of ng-template and viewContainerRef, but I do not know how to instantiate the provided component Type and insert into the desired area.
A simple example:
<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>
There are different options:
1) Built-in structural directive ngComponentOutlet
<ng-container *ngComponentOutlet="data.component"></ng-container>
2) Using angular material cdk. More precisely you can use PortalModule
from secondary entry point @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);
}
dialog.component.html
<ng-template [cdkPortalOutlet]="portal"></ng-template>
3) Using Angular low-level API
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();
}
}
}
dialog.component.html
<ng-template #target></ng-template>