$ применить в 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.

Другие вопросы по тегам