How to wait that ngAfterViewInit() runs while creating instance of a component from a directive?
Asked Answered
M

2

6

I have a directive that is creating in code an instance of component template he uses and set its innerHTml, which will change the tempalte dimension:

  var factory = this.resolver.resolveComponentFactory(MyComponentTemplate);
  this.templateComponent = this.viewContainerRef.createComponent(factory);

  this.templateComponent.instance.htmlStr = anyText;

Now, here is the problem. At this stage I will get undefined on the component sizes:

console.log(this.templateComponent.instance.width);    //undefined
console.log(this.templateComponent.instance.height);   //undefined

In debug I noticed that only after my component runs ngAfterViewInit(), only then I can read the component template width and height from my directive and use that values.

Is there a way I can tell my directive to wait until ngAfterViewInit() ends, and than do what I need from my directive with that info I'm looking for.

Methylene answered 27/4, 2017 at 8:18 Comment(2)
Why does this need to be in ngAfterViewInit? Why don't you just put it after this.createComponent()? You might need to inject ChangeDetectorRef and call cdRef.detectChanges() first.Spry
You absolutly right. After calling detectChanges it worked. Thanks a lot, you saved me a lot of tourbleMethylene
G
3
constructor(private cdRef:ChangeDetectorRef) {}

...

  var factory = this.resolver.resolveComponentFactory(MyComponentTemplate);
  this.templateComponent = this.viewContainerRef.createComponent(factory);
  this.templateComponent.instance.htmlStr = anyText;

  this.cdRef.detectChanges(); // run change detection immediately

  console.log(this.templateComponent.instance.width);    //undefined
  console.log(this.templateComponent.instance.height);   //undefined
Guerdon answered 27/4, 2017 at 8:59 Comment(0)
C
5

Using a globally injected ChangeDetectorRef isn't necessary and may not work. You can rely on the ComponentRef's changeDetectorRef method :

var factory = this.resolver.resolveComponentFactory(MyComponentTemplate);
this.templateComponent = this.viewContainerRef.createComponent(factory);
this.templateComponent.instance.htmlStr = anyText;

this.templateComponent.changeDetectorRef.detectChanges();
Cambrai answered 20/11, 2019 at 11:3 Comment(0)
G
3
constructor(private cdRef:ChangeDetectorRef) {}

...

  var factory = this.resolver.resolveComponentFactory(MyComponentTemplate);
  this.templateComponent = this.viewContainerRef.createComponent(factory);
  this.templateComponent.instance.htmlStr = anyText;

  this.cdRef.detectChanges(); // run change detection immediately

  console.log(this.templateComponent.instance.width);    //undefined
  console.log(this.templateComponent.instance.height);   //undefined
Guerdon answered 27/4, 2017 at 8:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.