1

I'm having the following directive that adds dynamic component to ng-container

@Directive({
    selector: '[appAddingDirective]'
})
export class AddingDirective {

    constructor(protected vc: ViewContainerRef) { }

    public addComponent(factory: ComponentFactory<any>, inputs: any): void {
        this.vc.clear();
        const ref: ComponentRef<any> = this.vc.createComponent(factory);
        Object.assign(ref.instance, inputs); // can't find more elegant way to assign inputs((
        ref.instance.ngOnInit(); // IMPORTANT: if I remove this call ngOnInit will not be called
    }
}

The directive is used in an obvious way.

@Component({
    selector: 'app-wrapper',
    template: `<ng-container appAddingDirective></ng-container>`
})
export class WrapperComponent implements AfterViewInit{
    @ViewChild(DynamicItemDirective)
    private dynamicItem: DynamicItemDirective;

    constructor() { }

    ngAfterViewInit(): void {
        // hope it doesn't matter how we get componentFactory
        this.dynamicItem.addComponent(componentFactory, {a: '123'});
    }
}

Finally in a component that is loaded dynamically I have

@Component({
    selector: 'app-dynamic',
    template: '<p>Dynamic load works {{ a }}</p>'
})
export class DynamicComponent implements OnInit {
    @Input() a: string;

    constructor() {}

    ngOnInit(): void {
        console.log(this.a);
        debugger;
    }

}

Here are my questions.

  1. If I remove ref.instance.ngOnInit() call in AddingDirective, I do not get in ngOnInit of DynamicComponent (debugger and console.log do not fire up). Do component lifecycle hooks work in a component that is created and attached dynamically? What is the best way to make these hooks work?
  2. I don't see rendered string Dynamic load works 123 still if I remove {{ a }} in template (template: '<p>Dynamic load works</p>'), Dynamic load works is rendered as it should. What is the reason and how can I fix that?
  3. Is there a better way to assing inputs than doing Object.assign(ref.instance, inputs) as above?

PS. I'm using Angular 11

Eugeny89
  • 3,797
  • 7
  • 51
  • 98
  • 1
    I think this answer pretty much covers it -> https://stackoverflow.com/questions/56427104/when-is-oninit-event-triggered-for-a-dynamically-loaded-angular-component – Alexus Dec 14 '20 at 10:52

0 Answers0