Search code examples
angularangular13

Angular 13 Directive viewContainerRef.createComponent pass object to created component


The code below with Dynamically create a component in Angular 13

The Directive:

import { Directive, Input, ViewContainerRef, Type } from '@angular/core';

@Directive({
  selector: '[appLoader]'
})
export class LoaderDirective {

  @Input() appLoader!: Type<any>;

  constructor(private viewContainerRef: ViewContainerRef) {}

  ngOnInit(): void {
    this.viewContainerRef.createComponent(this.appLoader);
  }

}

app.component.html

<div [appLoader]="component"></div>

app.component.ts

component = MyComponent

I also need to pass an object into the component that's created which is some extra information which will be used by the created component.

How can I do that?


Solution

  • I imagine you directive can be some like

    export class LoaderDirective {
    
      @Input() appLoader!: Type<any>;
      @Input() arg:any;  //<--you pass as arg any object
    
      //you need inject ComponentFactoryResolver
      constructor(private viewContainerRef: ViewContainerRef,
                  private componentFactoryResolver: ComponentFactoryResolver) {}
    
      ngOnInit(): void {
        //first you "create" a component
        const component=this.componentFactoryResolver.resolveComponentFactory(this.appLoader)
        //in componentRef you get a instance of the component
        const componentRef=this.viewContainerRef.createComponent(component);
    
        //you can access to the component using componentRef.instance
        //e.g. componentRef.instance.someMethod()
        //     componentRef.instance.prop="what-ever"
    
        //I choose use the object pass in the "arg" Input
        Object.keys(this.arg).forEach(x=>{
          componentRef.instance[x]=this.arg[x]
        })
      }
    

    You use like

    <div [appLoader]="component" [arg]="{name:'Angular'}"></div>
    

    See a fool stackblitz