web-dev-qa-db-fra.com

Déclenchement manuel de la détection de changement dans Angular

J'écris un composant Angular ayant une propriété Mode(): string.

Je souhaite pouvoir définir cette propriété par programme, pas en réponse à un événement.

Le problème est qu'en l'absence d'événement de navigateur, un modèle de liaison {{Mode}} ne se met pas à jour.

Existe-t-il un moyen de déclencher cette détection de changement manuellement?

330
jz87

Essayez l'une de celles-ci:

  • ApplicationRef.tick() - semblable au $rootScope.$digest() de AngularJS - c.-à-d., consulter l’arborescence complète du composant
  • NgZone.run(callback) - similaire à $rootScope.$apply(callback) - c'est-à-dire, évaluez la fonction de rappel à l'intérieur de la zone Angular. Je pense, mais je ne suis pas sûr, que cela finira par vérifier l’arborescence complète des composants après avoir exécuté la fonction de rappel.
  • ChangeDetectorRef.detectChanges() - semblable à $scope.$digest() - c'est-à-dire, vérifiez uniquement ce composant et ses enfants

Vous pouvez injecter ApplicationRef, NgZone ou ChangeDetectorRef dans votre composant.

559
Mark Rajcok

J'ai utilisé une référence de réponse acceptée et voudrais mettre un exemple, puisque la documentation de Angular 2 est très difficile à lire, j'espère que cela sera plus facile:

  1. Importer NgZone:

    import { Component, NgZone } from '@angular/core';
    
  2. Ajoutez-le à votre constructeur de classe

    constructor(public zone: NgZone, ...args){}
    
  3. Exécuter du code avec zone.run:

    this.zone.run(() => this.donations = donations)
    
110
juanpastas

J'ai pu mettre à jour avec markForCheck ()

Importer ChangeDetectorRef

import { ChangeDetectorRef } from '@angular/core';

Injecter et instancier

constructor(private ref: ChangeDetectorRef) { 
}

Enfin, marquez la détection du changement à avoir lieu

this.ref.markForCheck();

Voici un exemple où markForCheck () fonctionne et detectChanges () pas.

https://plnkr.co/edit/RfJwHqEVJcMU9ku9XNE7?p=preview

EDIT: Cet exemple ne décrit plus le problème :( Je pense qu’il pourrait utiliser une version plus récente de la version Angular dans laquelle il est corrigé.

(Appuyez sur STOP/RUN pour le relancer)

60
Nuno Tomas

Dans Angular 2+, essayez le décorateur @Input

Il autorise certaines liaisons de propriété Nice entre les composants parent et enfant.

Commencez par créer une variable globale dans le parent pour contenir l’objet/la propriété qui sera transmis à l’enfant.

Créez ensuite une variable globale dans l’enfant pour contenir l’objet/la propriété transmis du parent.

Ensuite, dans le code HTML parent, où le modèle enfant est utilisé, ajoutez une notation entre crochets avec le nom de la variable enfant, puis définissez-la égale au nom de la variable parent. Exemple:

<child-component-template [childVariable] = parentVariable>
</child-component-template>

Enfin, là où la propriété enfant est définie dans le composant enfant, ajoutez le décorateur d’entrée:

@Input()
public childVariable: any

Lorsque votre variable parent est mise à jour, elle doit transmettre les mises à jour au composant enfant, qui mettra à jour son code HTML.

De plus, pour déclencher une fonction dans le composant enfant, jetez un coup d'œil à ngOnChanges.

6
Jeremy Swagger

ChangeDetectorRef.detectChanges () - similaire à $ scope. $ Digest () - c'est-à-dire, vérifiez uniquement ce composant et ses enfants

0
Chetann