Причина, по которой я пишу это, заключается в том, что я время от времени читаю об Angular bootstrap (из нескольких источников). На этот раз я соберу их все и запишу.

Браузер

Все начинается с браузера.

Механизм рендеринга браузера начинается с получения содержимого запрошенного документа и анализа HTML документа для преобразования элементов в узлы DOM. .

После завершения синтаксического анализа браузер помечает документ как интерактивный и начинает анализировать скрипты, находящиеся в отложенном режиме (при добавлении к скрипту атрибута отложить это выполняется только после того, как документ был проанализирован, но до запуска DOMContentLoaded). На этом этапе состояние документа устанавливается как завершено и запускается событие загрузка.

(Подробнее о Как работают браузеры можно прочитать в блоге Тали Гарсиэль и Пола Айриша)

Начальная загрузка

На данный момент существует два способа инициализации Angular:

Автоматическая инициализация

После выполнения всех отложенных скриптов браузер запускает событие DOMContentLoaded, и Angular инициализируется автоматически.

После этого Angular ищет директиву «ngApp», которая обозначает корень нашего приложения. Если директива найдена, то запускается процесс начальной загрузки:

1. Загружается модуль, связанный с директивой;

<html ng-app="moduleName">
</html>

2. Создается $injector, который будет использоваться для внедрения зависимостей;

3. Инжектор создает $rootScope, который будет контекстом для модели приложения, и $compile, который будет отвечать за компиляцию HTML/DOM в шаблон и создать функцию шаблона. Эта функция шаблона затем используется для связывания области действия и шаблона вместе;

4. Angular скомпилирует DOM, начиная с корневого элемента «ngApp», и по пути обработает все директивы и привязки;

Ручная инициализация

Другой вариант — инициализация Angular вручную, что в данном случае происходит, когда сценарий «angular.js» оценивается после того, как для состояния готовности документа установлено значение «complete».

На данном этапе мы можем загрузить наше приложение только вручную, вызвав angular.bootstrap». Это следует делать только после того, как мы определили все модули.

<html>
<body>
  <script>
    // We first define the modules.
    angular.module('myApp', []);

    // Then we call angular bootstrap on document ready.
    angular.element(document).ready(function() {
      angular.bootstrap(document, ['myApp']);
    });
  </script>
</body>
</html>

Заметь:

  • Мы предоставили элемент DOM, который является корнем нашего приложения Angular (т. е. document);
  • И массив модулей для загрузки в приложение (т. е. myApp), которые могут быть предопределенными модулями или функциями, которые будут вызываться как блоки конфигурации;

Кроме того, когда запускается процесс начальной загрузки:

1. Создается $injector (используется для внедрения зависимостей);

2. Инжектор создает $rootScope и $compile;

3. Angular компилирует корневой элемент DOM, предоставленный на «angular.bootstrap», и обрабатывает все директивы и привязки, найденные по пути;

Загрузка модуля

Независимо от того, как инициализируется Angular (автоматически или вручную), он будет загружать каждый модуль как набор блоков configuration и run.

  • Блоки конфигурации — выполняются на этапе регистрации и настройки поставщика. В блоки конфигурации можно вставлять только провайдеры и константы. Это необходимо для предотвращения случайного запуска служб до того, как они будут правильно настроены.
  • Блоки запуска — выполняются после создания поставщика и используются для кикстарта приложения. Он выполняется после настройки всех сервисов и создания инжектора. В блоки запуска можно вставлять только экземпляры и константы. Это необходимо для предотвращения настройки системы во время выполнения приложения.
angular
.module('myModule', [])
.constant('myConstant', 'myConstantValue') // constant name & value
  // This is an example of a constant value.
  // You can have as many of these as you want.
  // They have no dependencies.
  // It cannot be overridden by an Angular decorator.
  // Angular runs these first.
.config(function(injectables) { // provider-injector
  // This is an example of config block.
  // You can have as many of these as you want.
  // You can only inject Providers and Constants(not instances)
  // into config blocks.
  // Angular runs these second.
})
.run(function(injectables) { // instance-injector
  // This is an example of a run block.
  // You can have as many of these as you want.
  // You can only inject instances and Constants (not Providers)
  // into run blocks
  // Angular runs these third.
});

При загрузке сначала Angular применяет все константы, а затем блоки конфигурации в том же порядке, в котором они были зарегистрированы.

Зависимости

Поскольку модули могут зависеть от других модулей, это означает, что обязательные модули должны быть загружены до загрузки требуемого модуля.

Когда мы смотрим на блоки конфигурации и запуска, эти зависимости означают, что блоки конфигурации необходимых модулей должны запускаться до блока конфигурации требуемого модуля. То же самое относится и к беговым блокам.

angular.module('moduleA');
angular.module('moduleB', ['moduleA]);
angular.module('moduleC', ['moduleB']);
\\ Config Module A
\\ Config Module B
\\ Config Module C
\\ Run Module A
\\ Run Module B
\\ Run Module C

Конец

После завершения начальной загрузки у нас есть исполняемое приложение с двусторонней привязкой, которое теперь будет ожидать любых входящих событий браузера (таких как щелчки мышью, нажатие клавиши или HTTP-запросы). ответ), которые могут изменить нашу модель.