Son vous allez deux solutions!
1. Modifiez ChangeDetectionStrategy en OnPush
Pour cette solution, vous dites essentiellement angulaire:
Arrêtez de vérifier les changements; je le ferai seulement quand je saurai que c'est nécessaire
La solution rapide:
Modifiez votre composant pour qu'il utilise ChangeDetectionStrategy.OnPush
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent implements OnInit {
// ...
}
Avec cela, les choses ne semblent plus fonctionner. En effet, à partir de maintenant, vous devrez effectuer un appel Angular detectChanges()
manuellement.
this.cdr.detectChanges();
Voici un lien qui m'a aidé à comprendre ChangeDetectionStrategy à droite:
https://alligator.io/angular/change-detection-strategy/
2. Comprendre ExpressionChangedAfterItHasBeenCheckedError
Voici un petit extrait de la réponse de tomonari_t sur les causes de cette erreur, j'ai essayé de n'inclure que les parties qui m'ont aidé à comprendre cela.
L'article complet montre de vrais exemples de code sur chaque point montré ici.
La cause première est le cycle de vie angulaire:
Après chaque opération, Angular se souvient des valeurs utilisées pour effectuer une opération. Ils sont stockés dans la propriété oldValues de la vue du composant.
Une fois que les vérifications ont été effectuées pour tous les composants, Angular démarre le cycle de résumé suivant, mais au lieu d'effectuer des opérations, il compare les valeurs actuelles avec celles dont il se souvient du cycle de résumé précédent.
Les opérations suivantes sont en cours de vérification lors du cycle de digestion:
vérifiez que les valeurs transmises aux composants enfants sont les mêmes que les valeurs qui seraient utilisées pour mettre à jour les propriétés de ces composants maintenant.
vérifiez que les valeurs utilisées pour mettre à jour les éléments DOM sont les mêmes que les valeurs qui seraient utilisées pour mettre à jour ces éléments maintenant fonctionnent de la même manière.
vérifie tous les composants enfants
Et ainsi, l'erreur est générée lorsque les valeurs comparées sont différentes. , le blogueur Max Koretskyi a déclaré:
Le coupable est toujours le composant enfant ou une directive.
Et enfin, voici quelques exemples du monde réel qui provoquent généralement cette erreur:
- Services partagés
- Diffusion d'événements synchrones
- Instanciation dynamique des composants
Chaque échantillon peut être trouvé ici (plunkr), dans mon cas, le problème était une instanciation de composant dynamique.
De plus, par ma propre expérience, je recommande fortement à tout le monde d'éviter la setTimeout
solution, dans mon cas a provoqué une boucle "presque" infinie (21 appels dont je ne veux pas vous montrer comment les provoquer),
Je recommanderais de toujours garder à l'esprit le cycle de vie angulaire afin que vous puissiez prendre en compte la façon dont ils seraient affectés chaque fois que vous modifiez la valeur d'un autre composant. Avec cette erreur Angular vous dit:
Vous faites peut-être mal, êtes-vous sûr d'avoir raison?
Le même blog dit également:
Souvent, le correctif consiste à utiliser le bon crochet de détection de changement pour créer un composant dynamique
Un petit guide pour moi est de considérer au moins les deux choses suivantes lors du codage ( je vais essayer de le compléter au fil du temps ):
- Évitez de modifier les valeurs de composant parent à partir des composants de son enfant, à la place: modifiez-les à partir de son parent.
- Lorsque vous utilisez les directives
@Input
et, @Output
essayez d'éviter de déclencher des modifications de lyfecycle à moins que le composant ne soit complètement initialisé.
- Évitez les appels inutiles
this.cdr.detectChanges();
car ils peuvent déclencher plus d'erreurs, en particulier lorsque vous traitez avec beaucoup de données dynamiques
- Lorsque l'utilisation de
this.cdr.detectChanges();
est obligatoire, assurez-vous que les variables ( @Input, @Output, etc
) utilisées sont remplies / initialisées au crochet de détection droit ( OnInit, OnChanges, AfterView, etc
)
- Lorsque cela est possible, supprimez plutôt que cachez , ceci est lié aux points 3 et 4.
Aussi
Si vous voulez bien comprendre Angular Life Hook, je vous recommande de lire la documentation officielle ici: