Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically load a component inside a Material MatDialog

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> 
like image 508
Jake Shakesworth Avatar asked Feb 10 '18 17:02

Jake Shakesworth


People also ask

What is dynamic component loading in angular?

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 is the dynamic component?

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.


1 Answers

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

like image 104
yurzui Avatar answered Sep 19 '22 18:09

yurzui