1

我创建了一个具有输入属性text和公共属性的组件height。更改text组件的高度后,应计算并设置为height属性。

问题:在将文本设置为高度为 0 之后,似乎没有立即呈现 HTML。如果我在setTimeout()调用中读取元素的高度,我会得到正确的高度。

我将测试项目上传到 StackBlitz: https ://stackblitz.com/edit/angular-ivw9d7

该应用程序的作用是:

  1. 使用 lorem ipsum 设置 testComponent 的文本。
  2. 设置文本后立即获取高度并将其写入控制台。
  3. 设置文本后 2 秒正确获取高度并将其写入控制台。

在第 2 步中,高度为 0,在第 3 步中,高度为应有的高度。

4

2 回答 2

1

您正在做所有事情,只是在视图初始化后不检查日志。

将您的控制台添加到ngAfterViewInit()钩子中。您的视图本身未在ngOnInit()

ngAfterViewInit() {
    console.log(`height right after changing is ${this.testComponent.height}`);
}

调试

当您尝试获取元素的高度时ngOnInit(),请尝试将其添加到控制台:

console.log(JSON.stringify(this.testComponent.el));

您将在控制台中看到输出:{"nativeElement":{}} 看,没有元素,所以没有高度。(注意:“字符串化”控制台很重要,否则日志将具有更新的值)。

无需调用手动更改检测和 setTimeouts 来获取更新的值。

于 2018-12-08T17:35:15.227 回答
1

text属性与的属性TestComponent绑定:testTextAppComponent

<app-test-component #testComponent [text]="testText"></app-test-component>

text并且当在以下位置修改属性时触发更改检测TestComponent

@Input() set text(value: string) {
  this._text = value;
  this.cd.markForCheck();
  this.cd.detectChanges();
}

问题是当你修改testTextin时AppComponenttext属性设置器 inTestComponent只会在下一个变化检测周期被调用。testText您可以通过在修改后立即强制更改检测来消除延迟AppComponent

this.testText = "Some new text";
this.cd.detectChanges();
console.log(`height right after changing is ${this.testComponent.height}`);

为确保修改后始终触发更改检测testText,您可以将其定义为 getter/setter 属性,并ChangeDetectorRef.detectChanges在 setter 中调用:

public _testText = '';

get testText(): string {
  return this._testText;
}
set testText(value: string) {
  this._testText = value;
  this.cd.detectChanges();
}

有了该代码,您无需在TestComponent.

请参阅此 stackblitz以获取演示。

于 2018-12-08T18:44:06.750 回答