Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 725
AngularOne Avatar asked Apr 27 '17 08:04

AngularOne


People also ask

How many times does ngAfterViewInit get called?

It is invoked only once when the directive is instantiated. ngAfterViewInit() is called once after ngAfterContentChecked(). ngAfterViewInit() is called after all child components are initialized and checked.

What is use of ngAfterViewInit?

ngAfterViewInit is useful when you want to call a lifecycle hook after all child components have been initialized and checked.

What is the difference between ngOnInit and ngAfterViewInit?

ngOnInit() is called right after the directive's data-bound properties have been checked for the first time, and before any of its children have been checked. It is invoked only once when the directive is instantiated. ngAfterViewInit() is called after a component's view, and its children's views, are created.

What is Afterviewinit in angular?

ngAfterViewInit()linkA callback method that is invoked immediately after Angular has completed initialization of a component's view. It is invoked only once when the view is instantiated.

How does ngafterviewinit work?

The view always loads right after the content. ngAfterViewInit waits on @ViewChild (ren) queries to resolve. These elements are queried from within the same view of the component.

When ngafterviewinit () is executed in angular?

But it is good practice to add interfaces to TypeScript directive classes in order to benefit from strong typing and editor tooling. ngAfterViewInit () is executed after Angular initializes the component's views and child views.

What are afterviewinit aftercontentinit afterviewchecked & aftercontentchecked?

AfterViewInit, AfterContentInit, AfterViewChecked & AfterContentChecked are the life cycle hooks. Angular raise them during the lifecycle of a Component. In this tutorial, we will learn what are they and when Angular invokes them. We also learn the difference between the AfterViewInit Vs AfterContentInit Vs AfterViewChecked & AfterContentChecked.

What is the aftercontentinit hook in angular?

The AfterContentInit is the Life cycle hook that angular calls after the Component’s content has been fully initialized and injected into Components View. Angular also updates the properties decorated with the ContentChild and ContentChildren before raising this hook. Angular calls this hook even if there is no projected content in the component


2 Answers

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
like image 174
Günter Zöchbauer Avatar answered Oct 03 '22 03:10

Günter Zöchbauer


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();
like image 41
Robin Avatar answered Oct 03 '22 01:10

Robin