Подтвердить что ты не робот

AngularJS - почему требуется $apply для правильного решения обещания $q?

Я пытаюсь написать небольшую услугу в моем приложении angular, которое позволит мне выбрать параметры конфигурации, указанные в глобальных объектах Javascript. Я не хочу пытаться получить доступ к глобальному объекту конфигурации, если документ не готов (потому что я не могу гарантировать порядок, в котором элементы script будут вставлены в HTML).

Однако я не могу понять, зачем мне нужен вызов $apply, чтобы разрешение действительно распространялось на обратный вызов then.

myModule.service('GlobalConfigService', ['$q', '$rootScope', function($q, $rootScope) {
    var def = $q.defer();
    $(document).ready(function() {
        def.resolve(MyConfig.val);
        $rootScope.$apply();
    });

    def.promise.then(function () {
        console.log('I am called only when $apply() is called. Why?');
    });

    return def.promise;
}]);
4b9b3361

Ответ 1

В AngularJS результаты решения() распространяются асинхронно, внутри цикла digest, а не сразу. Это означает, что обратные вызовы, зарегистрированные с помощью then(), будут вызваны (позже), когда произойдет цикл дайджест.

В вашем коде ничего не вызывает Angular для ввода цикла дайджеста, поэтому обратный вызов then() никогда не вызывается. Вызов $apply() - один из способов вызвать цикл дайджеста. Другой способ: добавить кнопку с ng-кликом, которая ничего не делает, а затем щелкнуть по ней, это вызовет цикл дайджеста, и вы увидите результаты:

<button ng-click="">Force digest by clicking me</button>

См. также fooobar.com/info/175445/...