$ применить в setTimeout
Я знаю что $apply
используется для соединения контекста Javascript и контекста AngularJS.
Простой пример ниже:
шаблон:
<div>{{someVal}}</div>
JavaScript в контроллере:
setTimeout(function() {
scope.$apply(function(){scope.someVal = 123});
}, 1000);
Нам нужно использовать $apply
в вышеуказанной ситуации.
Первое кормление:
Если я изменю JavaScript выше, чтобы:
setTimeout(function() {
scope.someVal = 123;
}, 1000);
scope.$watch('someVal', function(val) {
console.info(someVal);
});
Нет консоли о someVal, модифицированной до 123... Почему? Разве мы не можем наблюдать выражение, измененное в обратном вызове тайм-аута?
Второй вопрос:
Если мы используем директиву ngSwitch, как показано ниже:
<div ng-switch on="sub">
<div ng-switch-when="a">
//state a
</div>
<div ng-switch-when="b">
//state b
</div>
</div>
Когда я изменяю sub
в контроллере:
scope.sub = 'a';
setTimeout(function() {
scope.sub = 'b';
}, 1000);
Не нужно использовать $apply
!!!! Зачем?
Я обнаружил, что использование директивы ngSwitch $watch
контролировать on
значение атрибута. Почему ngSwitch может наблюдать за измененным атрибутом области в обратном вызове тайм-аута?
Пожалуйста скажите мне причину о 2 предложениях выше.
3 ответа
Из документации AngularJs
$apply() используется для выполнения выражения в угловом формате за пределами угловой структуры. (Например, из событий DOM браузера, setTimeout, XHR или сторонних библиотек). Поскольку мы обращаемся к угловой структуре, нам нужно выполнить надлежащий жизненный цикл области обработки исключений, выполняя наблюдения.
window.setTimeout - это функция JavaScript, поэтому все, что вы используете setTimeout
Вы должны использовать $apply() для обновления модели.
Ваш второй пример не будет работать без$apply()
Я сделал демо, чтобы уточнить $watch
а также $apply
вопрос. Пожалуйста, проверь это.
Вы можете использовать $timeout, который является оболочкой для window.setTimeout, а также таким образом вам не нужно будет использовать $ apply для обратного вызова:
$timeout (function () {scope.someVal = 123;}, 1000);
Когда вы запускаете код, который находится за пределами Angular, вам нужен способ сообщить Angular и наблюдателям этого значения, что оно изменилось. Вот для чего применяется $ apply, это позволит наблюдателям увольнять
Что касается второго вопроса, почему область обновляется без $ apply, вы должны как-то косвенно запустить $apply/$digest. Чтобы дать вам более конкретный ответ, Plunker будет необходимо проверить, что еще происходит в вашем коде.
Используйте службу $ timeout Angularjs вместо setTimeout, и вам не потребуется $apply. То же самое, если вы используете HTTP-вызов jquery, используйте угловой сервис http, чтобы избежать использования $apply.