108 votes

Angulaire 2: Comment détecter les changements dans un tableau? (@entrée de la propriété)

J'ai un composant parent qui récupère un tableau d'objets à l'aide d'une requête ajax.

Ce composant a deux enfants volets: l'Un d'eux montre les objets de l'arborescence et de l'autre on rend son contenu dans un format de tableau. Le parent passe le tableau de leurs enfants par le biais d'un @entrée de la propriété et ils affichent le contenu correctement. Tout comme prévu.

Le problème se produit lorsque vous modifiez un champ dans l'objet: l'enfant composants ne sont pas informés de ces changements. Les changements sont déclenchés seulement si vous avez manuellement réaffecter le tableau à sa variable.

Je suis habitué à travailler avec knock-out JS et j'ai besoin d'obtenir un effet similaire à celui de observableArrays.

J'ai lu quelque chose à propos de DoCheck mais je ne suis pas sûr de savoir comment il fonctionne.

137voto

Seid Mehmedovic Points 6522

OnChanges Cycle de vie du Crochet déclenche uniquement lors de la saisie des biens de l'exemple des changements.

Si vous voulez vérifier si un élément à l'intérieur du tableau d'entrée ont été ajoutés, déplacés ou supprimés, vous pouvez utiliser IterableDiffers à l'intérieur de l' DoCheck Cycle de vie du Crochet comme suit:

constructor(private _iterableDiffers: IterableDiffers) {
    this.iterableDiffer = this._iterableDiffers.find([]).create(null);
}

ngDoCheck() {
    let changes = this.iterableDiffer.diff(this.inputArray);
    if (changes) {
        console.log('Changes detected!');
    }
}

Si vous avez besoin de détecter les changements dans les objets à l'intérieur d'un tableau, vous aurez besoin de parcourir tous les éléments, et de les appliquer KeyValueDiffers pour chaque élément. (Vous pouvez le faire en parallèle avec le contrôle précédent).

Visitez ce post pour plus d'informations: Détecter les changements dans les objets à l'intérieur de la matrice de dans Angular2

36voto

Wojciech Majerski Points 807

Vous pouvez toujours créer une nouvelle référence pour le tableau en le fusionnant avec un tableau vide:

this.yourArray = [{...}, {...}, {...}];
this.yourArray[0].yourModifiedField = "whatever";

this.yourArray = [].concat(this.yourArray);

Le code ci-dessus va changer la référence de tableau et il va déclencher l'OnChanges mécanisme chez les enfants de composants.

12voto

Jan Cejka Points 151

Lire la suite de l'article, ne manquez pas mutable vs des objets immuables.

La question clé est que vous muter les éléments du tableau, tandis que le tableau de référence reste la même. Et Angular2 détection de changement de chèques uniquement de la matrice de référence pour détecter les changements. Après vous comprenez le concept des objets immuables, vous comprendrez pourquoi vous avez un problème et comment le résoudre.

J'utilise redux stocker dans un de mes projets pour éviter ce genre de problèmes.

https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

12voto

Günter Zöchbauer Points 21340

Vous pouvez utiliser IterableDiffers

Il est utilisé par des *ngFor

constructor(private _differs: IterableDiffers) {}

ngOnChanges(changes: SimpleChanges): void {
  if (!this._differ && value) {
     this._differ = this._differs.find(value).create(this.ngForTrackBy);
  }
}

ngDoCheck(): void {
  if (this._differ) {
    const changes = this._differ.diff(this.ngForOf);
    if (changes) this._applyChanges(changes);
  }
}

4voto

bess Points 21

Cela apparaît déjà répondu. Cependant, pour des problèmes futurs demandeurs d', je voulais ajouter quelque chose manqué quand je faisais des recherches et débogage d'un changement de détection de problème que j'ai eu. Maintenant, ma question était un peu isolé, et, certes, une erreur stupide sur ma fin, mais néanmoins pertinentes. Lorsque vous mettez à jour les valeurs dans l' Array ou Object en référence, vous assurer que vous êtes dans le bon champ. Je me suis fixé dans un piège en utilisant setInterval(myService.function, 1000)myService.function() permettrait de mettre à jour les valeurs d'un tableau public, j'ai utilisé à l'extérieur du service. Cela n'a jamais réellement mis à jour le tableau, comme la liaison et l'utilisation correcte doit avoir été setInterval(myService.function.bind(this), 1000). J'ai perdu mon temps à essayer de détection de modification de hacks, quand il était un idiot/simple bévue. Éliminer portée comme un coupable, avant d'essayer de changer des solutions de détection; il pourrait vous faire économiser un peu de temps.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X