Comment puis-je dire à AngularJS de «rafraîchir»


168

J'ai un événement de clic qui se produit en dehors de la portée de ma directive personnalisée, donc au lieu d'utiliser l'attribut "ng-click", j'utilise un écouteur jQuery.click () et j'appelle une fonction à l'intérieur de ma portée comme ceci:

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

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

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

À mon avis, 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 sur false, mais la vue AngularJS ne se met pas à jour. Existe-t-il un moyen de demander manuellement à Angular de mettre à jour la vue? Ou y a-t-il une approche plus «angulaire» pour résoudre ce problème que je ne vois pas?

Réponses:


315

La solution était d'appeler ...

$scope.$apply();

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



6
cela ne devrait-il pas être $scope.$apply();?
ErichBSchulz

Vous pouvez utiliser à la fois $ scope ou scope, c'est juste une différence de notation mais il en résulte la même chose.
user1226868

4
@ErichBSchulz -Souvent dans les directives, je vois la portée utilisée sans le $ qui, je crois, est susceptible de le différencier du «$ scope» qui est injecté dans les contrôleurs. Dans les contrôleurs, il est important de référencer par $ scope pour que Angular sache quelle dépendance injecter, alors que dans une fonction de lien directive, il passe toujours les 4 mêmes éléments par ordinal et ne nécessite pas de nom spécifique (scope, element, attrs, controller ).
cchamberlain

30

Pourquoi $applydevrait être appelé?

TL; DR : $applydoit être appelé chaque fois que vous souhaitez appliquer des modifications effectuées en dehors du monde angulaire.


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

$apply()est utilisé pour exécuter une expression dans AngularJS depuis l'extérieur du framework AngularJS. (Par exemple, à partir d'événements DOM du navigateur, setTimeout, XHR ou des bibliothèques tierces). Parce que nous appelons au framework AngularJS, nous devons effectuer un cycle de vie de portée approprié de la gestion des exceptions , en exécutant des montres .

Angular permet à toute valeur d'être utilisée comme cible de liaison. Ensuite, à la fin de tout 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 en fait une méthode, $scope.$digest()1 . Nous ne l'appelons presque jamais directement, comme nous l'utilisons à la $scope.$apply()place (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'une $watchvie à l'intérieur de la portée. Donc, si vous modifiez le modèle en dehors du contexte angulaire, vous devrez appeler $scope.$apply()pour que ces modifications soient propagées, sinon Angular ne saura pas qu'elles ont été modifiées, donc la liaison ne sera pas mise à jour 2 .


14

Utilisation

$route.reload();

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


5
De plus, lorsque vous utilisez ui-router, assurez-vous d'utiliser$state.reload()
Jeffrey Roosendaal

Cela a été très utile pour nos tests de capture d'écran! Nous simulons l'état, mais parfois, nous n'avons pas nécessairement d'observateurs qui surveillent les changements, ce qui peut entraîner des pannes déroutantes ou des pannes intermittentes. Mais être capable de recharger la lunette de cette manière aide à lutter contre cela.
theblang
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.