Как я могу сказать AngularJS «обновить»

168

У меня есть событие click, которое происходит вне области моей пользовательской директивы, поэтому вместо использования атрибута «ng-click» я использую слушатель jQuery.click () и вызываю функцию внутри моей области следующим образом:

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

close () - это простая функция, которая выглядит следующим образом:

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

На мой взгляд, у меня есть элемент с «ng-show», связанный с isOpen, например:

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

При отладке я обнаружил, что close () вызывается, isOpen обновляется до false, но представление AngularJS не обновляется. Есть ли способ, которым я могу вручную сказать Angular обновить вид? Или есть более «угловой» подход к решению этой проблемы, которого я не вижу?

Dustin
источник

Ответы:

315

Решение было позвонить ...

$scope.$apply();

... в моем обратном вызове события jQuery.

Dustin
источник
9
Эта ссылка будет полезной, я думаю. jimhoskins.com/2012/12/17/angularjs-and-apply.html
Роман Скляров
6
не должно ли это быть $scope.$apply();?
ErichBSchulz
Вы можете использовать как $ scope, так и scope, это просто разница в нотации, но результат будет одинаковым.
user1226868
4
@ErichBSchulz - Часто в директивах я вижу, что область видимости используется без символа $, который, как я полагаю, скорее всего будет отличать его от «области действия $», которая вводится в контроллеры. В контроллерах важно ссылаться на $ scope, чтобы Angular знал, какую зависимость вводить, тогда как в функции директивной ссылки он всегда передает те же 4 элемента по порядковому номеру и не требует определенного имени (scope, element, attrs, controller ).
cchamberlain
30

Зачем $applyзвонить?

TL; DR : $applyдолжен вызываться всякий раз, когда вы хотите применить изменения, сделанные за пределами мира Angular.


Просто чтобы обновить ответ @ Dustin , вот объяснение того, что именно $ apply делает и почему это работает.

$apply()используется для выполнения выражения в AngularJS извне платформы AngularJS. (Например, из событий DOM браузера, setTimeout, XHR или сторонних библиотек). Поскольку мы обращаемся к платформе AngularJS, нам нужно выполнить надлежащий жизненный цикл области обработки исключений , выполняя наблюдения .

Angular позволяет использовать любое значение в качестве цели привязки. Затем в конце любого поворота кода JavaScript он проверяет, изменилось ли значение. Этот шаг, который проверяет, изменились ли какие-либо значения привязки, имеет метод, $scope.$digest()1 . Мы почти никогда не вызываем его напрямую, так как используем $scope.$apply()вместо этого (который будет вызывать $scope.$digest).

Angular отслеживает только те переменные, которые используются в выражениях, и все, что находится внутри объекта $watch. Поэтому, если вы изменяете модель вне контекста Angular, вам необходимо $scope.$apply()будет распространить эти изменения, иначе Angular не будет знать, что они были изменены, поэтому привязка не будет обновлена 2 .

Mistalis
источник
14

использование

$route.reload();

Не забудьте ввести $routeв ваш контроллер.

test30
источник
5
Также, при использовании ui-router, обязательно используйте$state.reload()
Джеффри Розендал
Это было очень полезно для наших скриншотов! Мы моделируем состояние, но иногда не обязательно иметь наблюдателей, которые следят за изменениями, которые могут привести к сбивающим с толку сбоям или периодическим сбоям. Но возможность перезагрузить прицел таким образом помогает бороться с этим.
Theblang