Как управлять Angular2" выражение изменилось после проверки " исключение, когда свойство компонента зависит от текущей даты и времени
мой компонент имеет стили, которые зависят от текущей даты. В моем компоненте у меня есть следующая функция.
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
вычисляется из текущей даты и времени. Цвет меняется, если dtoDate
в последние 24 часа.
точная ошибка заключается в следующем:
Expression has changed after it was checked. Previous value:
'hsl( 123, 80%, 49%)'. Current value: 'hsl( 123, 80%, 48%)'
Я знаю, что исключение появляется в режиме разработки только в тот момент, когда значение проверяется. Если проверенное значение отличается от обновленного значения, исключение составляет заброшенный.
поэтому я попытался обновить текущую дату и время в каждом жизненном цикле в следующем методе hook, чтобы предотвратить исключение:
ngAfterViewChecked()
{
console.log( "! changement de la date du composant !" );
this.dateNow = new Date();
}
...но безуспешно.
5 ответов:
выполнить обнаружение изменений явно после изменения:
import { ChangeDetectorRef } from '@angular/core'; constructor(private cdRef:ChangeDetectorRef) {} ngAfterViewChecked() { console.log( "! changement de la date du composant !" ); this.dateNow = new Date(); this.cdRef.detectChanges(); }
небольшой workaround для этой проблемы:
ngAfterViewInit() { // or ngOnInit or whatever setTimeout(() => { this.dateNow = new Date(); }); }
как упоминалось @leocaseiro на выпуск github.
я нашел 3 решения для тех, кто ищет простых решений.
двигался от
ngAfterViewInit
доngAfterContentInit
переезд в
ngAfterViewChecked
в сочетании сChangeDetectorRef
как предложил на #14748 (комментарий)держите с ngOnInit () но вызовите
ChangeDetectorRef.detectChanges()
после внесенные изменения.
Я думаю самое лучшее и самое чистое решение вы можете себе представить это:
@Component( { selector: 'app-my-component', template: `<p>{{ myData?.anyfield }}</p>`, styles: [ '' ] } ) export class MyComponent implements OnInit { private myData; constructor( private myService: MyService ) { } ngOnInit( ) { /* async .. await clears the ExpressionChangedAfterItHasBeenCheckedError exception. */ this.myService.myObservable.subscribe( async (data) => { this.myData = await data } ); } }
испытано с угловым 5.2.9