我的组件具有依赖于当前日期时间的样式。在我的组件中,我有如下函数。
private fontColor( dto : Dto ) : string {
// date d'exécution du dto
let dtoDate : Date = new Date( dto.LastExecution );
(...)
let color = "hsl( " + hue + ", 80%, " + (maxLigness - lightnessAmp) + "%)";
return color;
}
lightnessAmp从当前datetime开始计算。如果dtoDate在过去24小时内,则颜色会发生变化。
准确的错误如下:
表达式在检查后发生了变化。先前值:'hsl(123, 80%, 49%)'。当前值:'hsl(123, 80%, 48%)'
我知道异常只出现在开发模式的值被检查的时刻。如果检查值与更新值不同,则抛出异常。
因此,我尝试在以下钩子方法中更新每个生命周期的当前datetime,以防止异常:
ngAfterViewChecked()
{
console.log( "! changement de la date du composant !" );
this.dateNow = new Date();
}
...但是没有成功。
博士TL;
ngAfterViewInit() {
setTimeout(() => {
this.dateNow = new Date();
});
}
虽然这是一种变通方法,但有时真的很难以更好的方式解决这个问题,所以如果您使用这种方法,请不要责怪自己。没关系。
示例:初始问题[链接],用setTimeout()解决[链接]
如何避免
一般来说,这个错误通常发生在你添加ngAfterViewInit之后(甚至在父/子组件中)。第一个问题是问你自己,我能没有ngAfterViewInit吗?也许你把代码移到某个地方(ngAfterViewChecked可能是另一种选择)。
例如:[链接]
也
ngAfterViewInit中影响DOM的async也可能导致这个。也可以通过setTimeout或在管道中添加delay(0)操作符来解决:
ngAfterViewInit() {
this.foo$
.pipe(delay(0)) //"delay" here is an alternative to setTimeout()
.subscribe();
}
例如:[链接]
好的阅读
关于如何调试以及为什么会发生这种情况的好文章:链接
以前所有的解决方案都不适合我,这是唯一一个真正管用的。
错误信息示例:
AppComponent.html:1错误
ExpressionChangedAfterItHasBeenCheckedError:表达式已经改变
在检查之后。之前的值:'ngIf: true'。当前值:
“ngIf:假”。
在viewDebugError (core.js:20440)
在expressionChangedAfterItHasBeenCheckedError (core.js:20428)
...
解决方案
在触发问题的组件中导入ChangeDetectorRef, AfterContentChecked
然后加上:
ngAfterContentChecked(): void {
this.changeDetector.detectChanges();
}
例子
import { Component, OnInit, ChangeDetectorRef, AfterContentChecked } from '@angular/core';
import { Title } from '@angular/platform-browser';
import { environment } from '@env/environment';
import { LayoutService } from '@app/core/layout/layout.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: []
})
export class AppComponent implements OnInit, AfterContentChecked {
env = environment;
title = this.env.appName;
partials: any = {};
public constructor(
private titleService: Title,
public layout: LayoutService,
private changeDetector: ChangeDetectorRef,
) {}
ngOnInit() {
this.titleService.setTitle(this.env.appName);
this.layout.getLayout().subscribe(partials => {
this.partials = partials;
});
}
ngAfterContentChecked(): void {
this.changeDetector.detectChanges();
}
}
不是我的:这是来源
https://gist.github.com/vades/a225170304f34f88a7a5d48bf4b1f58c