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>
Dynamic component loadinglink New ad components are added frequently by several different teams. This makes it impractical to use a template with a static component structure. Instead, you need a way to load a new component without a fixed reference to the component in the ad banner's template.
What dynamic components are. Dynamic means, that the components location in the application is not defined at buildtime. That means, that it is not used in any angular template. Instead, the component is instantiated and placed in the application at runtime.
There are different options:
1) Built-in structural directive ngComponentOutlet
<ng-container *ngComponentOutlet="data.component"></ng-container>
Example
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>
Example
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>
Example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With