À partir de la documentation:
detectChanges (): void
Vérifie le détecteur de changement et ses enfants.
Cela signifie que s'il y a un cas où quelque chose à l'intérieur de votre modèle (votre classe) a changé mais qu'il n'a pas reflété la vue, vous devrez peut-être notifier Angular pour détecter ces changements (détecter les changements locaux) et mettre à jour la vue.
Les scénarios possibles pourraient être:
1- Le détecteur de changement est détaché de la vue (voir détacher )
2- Une mise à jour a eu lieu mais elle n'a pas été dans la zone angulaire, par conséquent, Angular ne le sait pas.
Comme lorsqu'une fonction tierce a mis à jour votre modèle et que vous souhaitez mettre à jour la vue après cela.
someFunctionThatIsRunByAThirdPartyCode(){
yourModel.text = "new text";
}
Étant donné que ce code est en dehors de la zone d'Angular (probablement), vous devez probablement vous assurer de détecter les modifications et de mettre à jour la vue, ainsi:
myFunction(){
someFunctionThatIsRunByAThirdPartyCode();
// Let's detect the changes that above function made to the model which Angular is not aware of.
this.cd.detectChanges();
}
REMARQUE :
Il existe d'autres façons de faire fonctionner ci-dessus, en d'autres termes, il existe d'autres façons d'apporter ce changement à l'intérieur du cycle de changement angulaire.
** Vous pouvez envelopper cette fonction tierce dans un zone.run:
myFunction(){
this.zone.run(this.someFunctionThatIsRunByAThirdPartyCode);
}
** Vous pouvez envelopper la fonction dans un setTimeout:
myFunction(){
setTimeout(this.someFunctionThatIsRunByAThirdPartyCode,0);
}
3- Il y a aussi des cas où vous mettez à jour le modèle une fois que le change detection cycle
est terminé, où dans ces cas vous obtenez cette erreur redoutée:
"L'expression a changé après avoir été vérifiée";
Cela signifie généralement (du langage Angular2):
J'ai vu un changement dans votre modèle qui a été causé par l'un de mes moyens acceptés (événements, requêtes XHR, setTimeout, et ...) puis j'ai exécuté ma détection de changement pour mettre à jour votre vue et je l'ai terminé, mais il y en a eu un autre fonction dans votre code qui a mis à jour le modèle à nouveau et je ne veux plus exécuter ma détection de changement car il n'y a plus de vérification sale comme AngularJS: D et nous devrions utiliser un flux de données à sens unique!
Vous rencontrerez certainement cette erreur: P.
Quelques façons de résoudre ce problème:
1- Bonne manière : assurez-vous que la mise à jour est dans le cycle de détection des changements (les mises à jour Angular2 sont un flux à sens unique qui se produit une fois, ne mettez pas à jour le modèle après cela et déplacez votre code vers un meilleur endroit / heure).
2- Méthode paresseuse : lancez detectChanges () après cette mise à jour pour rendre angular2 heureux, ce n'est certainement pas la meilleure façon, mais comme vous avez demandé quels sont les scénarios possibles, c'est l'un d'entre eux.
De cette façon, vous dites: je sais sincèrement que vous avez exécuté la détection des modifications, mais je veux que vous le refassiez car j'ai dû mettre à jour quelque chose à la volée après avoir terminé la vérification.
3- Mettez le code dans un setTimeout
, car il setTimeout
est patché par zone et s'exécutera une detectChanges
fois terminé.
À partir des documents
markForCheck() : void
Marque tous les ancêtres ChangeDetectionStrategy comme à cocher.
Ceci est principalement nécessaire lorsque la ChangeDetectionStrategy de votre composant est OnPush .
OnPush lui-même signifie, n'exécutez la détection de changement que si l'un de ces événements s'est produit:
1- L'une des @inputs du composant a été complètement remplacée par une nouvelle valeur, ou simplement, si la référence de la propriété @Input a complètement changé.
Donc, si ChangeDetectionStrategy de votre composant est OnPush et que vous avez:
var obj = {
name:'Milad'
};
Et puis vous le mettez à jour / le mutez comme:
obj.name = "a new name";
Cela ne mettra pas à jour la référence obj , donc la détection de changement ne fonctionnera pas, donc la vue ne reflète pas la mise à jour / la mutation.
Dans ce cas, vous devez indiquer manuellement à Angular de vérifier et de mettre à jour la vue (markForCheck);
Donc, si vous avez fait ceci:
obj.name = "a new name";
Vous devez faire ceci:
this.cd.markForCheck();
Au contraire, ci-dessous entraînerait l'exécution d'une détection de changement:
obj = {
name:"a new name"
};
Ce qui a complètement remplacé l'obj précédent par un nouveau {}
;
2- Un événement s'est déclenché, comme un clic ou quelque chose comme ça ou l'un des composants enfants a émis un événement.
Des événements comme:
- Cliquez sur
- Keyup
- Événements d'abonnement
- etc.
Donc en bref:
À utiliser detectChanges()
lorsque vous avez mis à jour le modèle après que Angular a exécuté sa détection de changement, ou si la mise à jour n'a pas du tout été dans le monde angulaire.
À utiliser markForCheck()
si vous utilisez OnPush et que vous contournez le en ChangeDetectionStrategy
faisant muter certaines données ou si vous avez mis à jour le modèle dans un setTimeout ;