I have created a component with an input attribute text
and a public property height
. After changing text
the height of the component should be computed and set to the height
property.
Problem: The HTML seems not to be rendered right after setting the text so that the height is 0. If I read the element's height in a setTimeout()
call, I get the right height.
I uploaded the test project to StackBlitz: https://stackblitz.com/edit/angular-ivw9d7
What the app does is:
In step 2. the height is 0, in step 3. the height is as it should be.
The text
property of the TestComponent
is bound to the testText
property of AppComponent
:
<app-test-component #testComponent [text]="testText"></app-test-component>
and you trigger change detection when the text
property is modified in the TestComponent
:
@Input() set text(value: string) {
this._text = value;
this.cd.markForCheck();
this.cd.detectChanges();
}
The problem is that when you modify testText
in AppComponent
, the text
property setter in TestComponent
will be called only at the next change detection cycle. You can elmininate the delay by forcing change detection as soon as testText
is modified in AppComponent
:
this.testText = "Some new text";
this.cd.detectChanges();
console.log(`height right after changing is ${this.testComponent.height}`);
To make sure that change detection is always triggered after modifying testText
, you could define it as a getter/setter property, and call ChangeDetectorRef.detectChanges
in the setter:
public _testText = '';
get testText(): string {
return this._testText;
}
set testText(value: string) {
this._testText = value;
this.cd.detectChanges();
}
With that code in place, you don't need to force change detection in the TestComponent
.
See this stackblitz for a demo.