web-dev-qa-db-fra.com

Comment puis-je dire à AngularJS de "rafraîchir"

J'ai un événement click qui se produit en dehors du champ d'application de ma directive personnalisée. Au lieu d'utiliser l'attribut "ng-click", j'utilise un écouteur jQuery.click () et j'appelle une fonction dans mon champ comme suit:

$('html').click(function(e) {
  scope.close();
);

close () est une fonction simple qui ressemble à ceci:

scope.close = function() {
  scope.isOpen = false;
}

De mon point de vue, j'ai un élément avec "ng-show" lié à isOpen comme ceci:

<div ng-show="isOpen">My Div</div>

Lors du débogage, je constate que close () est appelé, isOpen est mis à jour avec la valeur false, mais la vue AngularJS ne se met pas à jour. Est-il possible de dire manuellement à Angular de mettre à jour la vue? Ou existe-t-il une approche plus "angulaire" pour résoudre ce problème que je ne vois pas?

159
Dustin

La solution était d'appeler ...

$scope.$apply();

... dans mon rappel d'événement jQuery.

297
Dustin

Pourquoi $apply devrait-il être appelé?

TL; DR : $apply devrait être appelé chaque fois que vous souhaitez appliquer les modifications apportées en dehors de de Angular monde.


Juste pour mettre à jour @ la réponse de Dustin , voici une explication de ce que $ apply fait exactement et pourquoi cela fonctionne.

$apply() est utilisé pour exécuter une expression dans AngularJS en dehors du cadre AngularJS. (Par exemple, depuis les événements DOM du navigateur, setTimeout, XHR ou des bibliothèques tierces). Comme nous appelons le framework AngularJS, nous devons exécuter le cycle de vie de scope approprié de gestion des exceptions , exécution de surveillances .

Angular permet d'utiliser n'importe quelle valeur comme cible de liaison. Ensuite, à la fin de chaque tour de code JavaScript, il vérifie si la valeur a changé. Cette étape qui vérifie si des valeurs de liaison ont changé a réellement une méthode, $scope.$digest()1. Nous ne l'appelons presque jamais directement, car nous utilisons plutôt $scope.$apply() (qui appellera $scope.$digest).

Angular ne surveille que les variables utilisées dans les expressions et tout ce qui se trouve à l'intérieur d'un $watch vivant à l'intérieur de la portée. Donc, si vous modifiez le modèle en dehors du contexte Angular, vous devrez appeler $scope.$apply() pour que ces modifications soient propagées, sinon Angular ne saura pas qu'elles ont été modifié donc la liaison ne sera pas mise à jour2.

26
Mistalis

Utilisation

$route.reload();

n'oubliez pas d'injecter $route sur votre contrôleur.

13
test30