Jak mogę powiedzieć AngularJS, aby „odświeżył”

168

Mam zdarzenie kliknięcia, które ma miejsce poza zakresem mojej niestandardowej dyrektywy, więc zamiast używać atrybutu „ng-click”, używam odbiornika jQuery.click () i wywołuję funkcję w moim zakresie w następujący sposób:

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

close () to prosta funkcja, która wygląda następująco:

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

Moim zdaniem mam element z „ng-show” powiązany z isOpen w następujący sposób:

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

Podczas debugowania stwierdzam, że wywoływana jest metoda close (), isOpen jest aktualizowana do wartości false, ale widok AngularJS nie jest aktualizowany. Czy istnieje sposób, w jaki mogę ręcznie powiedzieć Angularowi, aby zaktualizował widok? Czy może jest bardziej „kątowe” podejście do rozwiązania tego problemu, którego nie widzę?

Dustin
źródło

Odpowiedzi:

315

Rozwiązaniem było zadzwonić ...

$scope.$apply();

... w moim wywołaniu zwrotnym zdarzenia jQuery.

Dustin
źródło
9
Myślę, że ten link będzie pomocny. jimhoskins.com/2012/12/17/angularjs-and-apply.html
Roman Sklyarov
6
nie powinno tak być $scope.$apply();?
ErichBSchulz
Możesz użyć zarówno zakresu, jak i zakresu, jest to tylko różnica w zapisie, ale daje to samo.
user1226868,
4
@ErichBSchulz -Często w dyrektywach widzę zakres używany bez znaku $, który, jak sądzę, prawdopodobnie odróżnia go od '$ scope', który jest wstrzykiwany do kontrolerów. W kontrolerach ważne jest, aby odwoływać się za pomocą $ scope, aby Angular wiedział, jaką zależność wstrzyknąć, podczas gdy w funkcji linku dyrektywy zawsze przekazuje te same 4 elementy według liczby porządkowej i nie wymaga określonej nazwy (zakres, element, atrybuty, kontroler ).
cchamberlain
30

Dlaczego $applynależy zadzwonić?

TL; DR : $applypowinno być wywoływane za każdym razem, gdy chcesz zastosować zmiany dokonane poza światem Angular.


Aby zaktualizować odpowiedź @ Dustina , oto wyjaśnienie, co dokładnie robi $ apply i dlaczego działa.

$apply()służy do wykonywania wyrażeń w AngularJS spoza frameworka AngularJS. (Na przykład ze zdarzeń DOM przeglądarki, setTimeout, XHR lub bibliotek innych firm). Ponieważ korzystamy z frameworka AngularJS, musimy przeprowadzić odpowiedni cykl życia zakresu obsługi wyjątków , wykonując zegarki .

Angular umożliwia użycie dowolnej wartości jako celu powiązania. Następnie na końcu każdej tury kodu JavaScript sprawdza, czy wartość uległa zmianie. Ten krok, który sprawdza, czy w rzeczywistości zmieniły się jakiekolwiek wiążące wartości, ma metodę $scope.$digest()1 . Prawie nigdy nie wywołujemy tego bezpośrednio, ponieważ używamy $scope.$apply()zamiast tego (co zadzwoni $scope.$digest).

Angular monitoruje tylko zmienne używane w wyrażeniach i wszystko, co $watchżyje wewnątrz zakresu. Jeśli więc zmieniasz model poza kontekstem Angular, będziesz musiał wywołać $scope.$apply()propagację tych zmian, w przeciwnym razie Angular nie będzie wiedział, że zostały zmienione, więc powiązanie nie zostanie zaktualizowane 2 .

Mistalis
źródło
14

Posługiwać się

$route.reload();

pamiętaj, aby wstrzyknąć $routedo kontrolera.

test30
źródło
5
Ponadto, używając routera ui, upewnij się, że używasz$state.reload()
Jeffrey Roosendaal
Było to bardzo pomocne w naszych testach zrzutów ekranu! Kpimy ze stanu, ale czasami niekoniecznie mamy obserwatorów, którzy obserwują zmiany, co może skutkować mylącymi awariami lub sporadycznymi awariami. Ale możliwość przeładowania lunety w ten sposób pomaga temu zaradzić.
theblang