Jak zarządzać wyjątkiem Angular2 "wyrażenie zmieniło się po sprawdzeniu", gdy właściwość komponentu zależy od bieżącej datetime
Mój komponent ma style, które zależą od bieżącej daty. W moim komponencie mam następującą funkcję.
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
jest obliczana z bieżącej datetime. Kolor zmienia się, jeśli dtoDate
jest w ciągu ostatnich 24 godzin.
Dokładny błąd jest następujący:
Expression has changed after it was checked. Previous value:
'hsl( 123, 80%, 49%)'. Current value: 'hsl( 123, 80%, 48%)'
Wiem, że wyjątek pojawia się w trybie deweloperskim tylko w momencie sprawdzania wartości. Jeśli sprawdzona wartość różni się od zaktualizowanej wartości, to wyjątek jest wyrzucany.
Więc próbowałem zaktualizować bieżąca datetime w każdym cyklu życia w następującej metodzie Hooka, aby zapobiec wyjątkowi:
ngAfterViewChecked()
{
console.log( "! changement de la date du composant !" );
this.dateNow = new Date();
}
...ale bez powodzenia.
5 answers
Uruchom wykrywanie zmian jawnie po zmianie:
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();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-18 19:20:08
To jest ładny post, aby zrozumieć ten błąd. To nie jest zbyt długo do czytania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-06 08:59:22
Małe obejście tego problemu:
ngAfterViewInit() { // or ngOnInit or whatever
setTimeout(() => {
this.dateNow = new Date();
});
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-15 14:56:56
Jak wspomniano przez @leocaseiro w wydaniu github.
Znalazłem 3 rozwiązania dla tych, którzy szukają łatwych poprawek.
Przejście z
ngAfterViewInit
dongAfterContentInit
Przeniesienie do
ngAfterViewChecked
w połączeniu zChangeDetectorRef
jako zasugerował: #14748 (skomentuj)Keep with ngOnInit () but call
ChangeDetectorRef.detectChanges()
after twoje zmiany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-07 23:49:22
Myślę, że najlepszym i najczystszym rozwiązaniem można sobie wyobrazić jest to:
@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 }
);
}
}
Testowane z Angular 5.2.9
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-29 19:31:41