如何解决Angular中的"Expression Changed After It Has Been Checked Error"?

How to solve the "Expression Changed After It Has Been Checked Error" in Angular?

我想在 Angular 中实现聊天。聊天的每个项目(消息)都有一个 header (title/name),它应该有一个特定的边距。边距应根据 div 的高度计算。代码如下所示。

<div *ngFor="let item of chatArray">
  <div #juliet [style.margin-top.px]= "-(juliet.clientHeight/2)">
  {{item.message}}
  </div>
</div>

问题出在 Chrome 浏览器中(在 Mozilla 中没有问题)。控制台错误是:“ExpressionChangedAfterItHasBeenCheckedError:检查后表达式已更改。以前的值:'margin-top: -40.5'。当前值:'margin-top: -40'。”

在 ts 文件中我尝试实现变化检测:

ngOnInit() {
//code for chat initialization
this.cdRef.detectChanges();
}

ngAfterViewInit() {
   this.cdRef.detectChanges();
}

ngAfterContentChecked() {
  this.cdRef.detectChanges();
}

如果我在 .ts 文件中添加

@Component({
  ...
  changeDetection: ChangeDetectionStrategy.OnPush
})

错误消失但边距小于应有的值。我想消除错误并根据 div 高度计算右边距。

如果您有任何想法,我将不胜感激。谢谢!

ngOnInit() .detectChanges 调用没有用,因为正在进行更改检测,并且将在评估 ngOnInit 挂钩后立即检查模板。

ngAfterViewInit 和 ngAfterContentChecked .detectChanges 调用是错误的,因为这些挂钩是在使用正确的数据更新模板后调用的。

尝试一下,可能会解决这个问题。创建指令

import { Directive, ElementRef } from '@angular/core';

@Directive({
  selector: '[appApplyMargin]'
})
export class ApplyMargin {
    constructor(el: ElementRef) {
       el.nativeElement.style.marginTop = 
              (el.nativeElement.clientHeight/2) + 'px'
    }
}

注意:如果需要将构造函数中的代码包装在 setTimeout