2
votes

La stratégie de détection onPush ne fonctionne pas dans angulaire 8

Je crée une application en angular 8 et je travaille actuellement sur un module de tableau de bord où j'ai un scénario dans lequel onPush Strategy ne semble pas fonctionner, je vais expliquer mon scénario avec la structure div si quelqu'un peut m'aider à ce sujet.

pre> XXX

Ci-dessus, le scénario dans lequel je modifie widget.widgetName dans le composant app-widget-settings , où app-widget-settings se compose d'une zone de texte qui est liée avec widget.widgetName en utilisant ngModel

<input type="text" [(ngModel)]="widget.widgetName">

ici mais mes modifications ne sont pas reflétées dans app-widget- body composant où j'utilise

changeDetection: ChangeDetectionStrategy.OnPush

si je supprime changeDetection de app-widget-body, les modifications sont reflétée.

Dans ce qui précède, que devons-nous utiliser pour que les modifications effectuées dans le composant app-widget-settings soient reflétées dans app-widget-body et je souhaite utiliser ChangeDetectionStrategy.OnPush.

Ci-dessous le lien pour stackblitz

https://stackblitz.com/edit /angular-gjdjzg?file=src%2Fapp%2Fapp.component.ts


0 commentaires

3 Réponses :


1
votes

C'est en fait le comportement attendu.

Chaque composant a sa propre référence de détection de changement, et lorsque vous changez la stratégie en stratégie OnPush , vous devez vous rappeler que pour provoquer le changer le détecteur en "cocher" vous devez passer une nouvelle référence de votre entrée.

Dans ce cas, vous venez de modifier l'une des propriétés du widget, mais vous n'avez pas vraiment changé sa référence. p>

Essayez d'émettre un événement à chaque fois que vous modifiez l'objet widget, puis, dans le composant conteneur, retournez simplement un nouvel objet remplaçant le changement. Quelque chose comme:

onNameChange(name: string){
   this.widget = {...this.widget, widgetName: name}
}


2 commentaires

Veuillez créer un stackblitz pour que je puisse détecter le problème


Bonjour, veuillez trouver le stackblitz ci-joint: stackblitz.com/edit/ …



1
votes

Vous devez "faire remonter" les modifications apportées au composant Dashboard pour qu'il recharge ( change sa référence ) son tableau de widgets:

https://stackblitz.com/edit/angular-mzxcbd

C'est fastidieux et pas très joli. En général, il n'est pas recommandé pour les objets profondément imbriqués. Une bonne approche alternative consiste à utiliser le modèle redux avec NGRX par exemple. Un magasin central contient vos données et n'importe quel composant peut y accéder, indépendamment de sa hiérarchie. Je le recommande fortement.


0 commentaires

1
votes

Lorsque vous utilisez ChangeDetectionStrategy.OnPush, vous devez suivre une règle ' Chaque variable qui ne provient pas de @Input (), est utilisée dans le modèle et peut être modifiée pendant la durée de vie du composant, doit être dans le modèle en tant que flux (observable) avec asynchrone de tube '

Angular dispose également de 3 classes pour les données réactives:

  • FormArray - pour les tableaux
  • FormGroup - pour les cartes
  • FormControl - pour des valeurs simples

Notez que vous ne devez modifier les données dans ces classes que via les API fournies, comme FormControl.setValue (valeur) pour qu'elles émettent un événement de changement, qui indiquera au tube asynchrone de déclencher le cycle de détection des modifications

Dans votre cas, j'utiliserais FormArray d'éléments FormGroup, qui auraient FormControl pour chaque champ.

L'accès aux champs serait comme

<input type="text" [formControl]="dataFormArray.at(widgetFormGroupIndex).get('widgetName')">

Vous devez également utiliser la directive de ReactiveFormsModule dans votre entrée, comme ceci

<div class="parent" *ngFor="widgetFormGroupIndex of widgetIndexList">
  {{ dataFormArray.at(widgetFormGroupIndex).get('widgetName').valueChanges | async }}
</div>

Pour plus d'informations, lisez https://angular.io/guide/reactive-forms

Notez également que vous ne devez pas appeler de méthodes dans les modèles (il les appelle à chaque changement cycle de détection), le code utilise des méthodes de simplicité. Au lieu d'appels func, vous devez soit créer des tubes purs (pour plus d'informations, lisez ici https://angular.io/guide/ pipes ) ou précalculez les résultats des appels func dans votre fichier component.ts, puis utilisez les résultats dans le modèle


0 commentaires