Пользователь
0,0
рейтинг
6 августа 2014 в 10:52

Разработка → AngularJS: настраиваем событие инициализации tutorial recovery mode

Если вы уже знаете, что такое AngularJS и пользуетесь им продолжительное время, вероятно перед вами уже стояла задача выполнения неких действий сразу после инициализации приложения. И после прочтения документации вы обнаруживаете, что такого способа “из коробки” нет)

Конечно, многие из вас вспомнят про метод run() внутри каждого модуля. Однако я отвечу вам, что этот метод срабатывает ДО инициализации приложения. Точнее после загрузки инжектором всех модулей, но до их выполнения. Это легко проверить.

angular.module("use", [])
  .config([function(){
    console.log("::use::config");
  }])
  .run([function(){
    console.log("::use::run");
  }])
  .controller("BarCtrl", ["$scope", function($scope){
    console.log("::use::ctrl::BarCtrl");
    $scope.foo = "bar";
  }])
;

Приведённый выше код выведет в консоль:

::use::config
::use::run
::use::ctrl::BarCtrl 

Живой пример.

И всё же есть способ оповестить приложение об инициализации. В этом нам поможет метод angular.bootstrap. Этот метод позволяет прикреплять модуль к DOM элементу без использования директивы ng-app. После того, как мы прикрепим модуль и в нём отработают все элементы, мы можем получить ссылку на $rootScope модуля из инжектора и оповестить все дочерние элементы. В AngularJS есть 2 метода работы с событиями — $emit и $broadcast. Отличие первого от второго в том, что он работает “вверх” и его может остановить любой родительский обработчик. В общем, прямой аналог событий DOM. Второй же оповещает “вниз” и его невозможно остановить. Оба метода начинают работу с текущей области видимости.

Итак, попробуем подвести итог всех рассуждений и показать уже этот кусок кода.

angular.element(document).ready(function(){
    var $inj = angular.bootstrap(document.body, ['use']);
    var $rootScope = $inj.get("$rootScope");
    
    $rootScope.$broadcast("init", "hello");
    $rootScope.$digest();
});

Живой пример

Поскольку мы находимся вне контекста AngularJS, необходимо самим запустить внутренний $digest() цикл. Как видно из консоли из примера по ссылке выше, событие запускается именно после работы всех компонентов модуля. Что, собственно, и требовалось.
Дмитрий Ц @ReklatsMasters
карма
3,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (5)

  • +5
    А можете привести пример, для которого необходима такая инициализация?
    • 0
      Поддерживаю вопрос. Непонятно зачем?
      По статье получается нужно что-то сделать после любого инициализированного контроллера?
  • +3
    А чем ng-init не устроил то?
  • 0
    Возможно, для ленивой загрузки модулей?
  • 0
    А повесить контроллер на body не проще? Ладно бы тут была возможность по promise загрузить что-то, например справочники, и продолжить выполнение приложения, а так от ng-init или контроллера не отличается, плюс без таких грязных методов.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.