Понимание ступенчатого ручного бутстрапинга angularJS

Я искал основы angularJS о том, как он загружается вручную. Я наткнулся на другой подход и нашел этот подход, чтобы лучше всего подойти.

angular.element(document).ready(function(){
   angular.bootstrap(document,['myapp'])
})

Двигаясь дальше, я встретил этот другой способ, который разбивает его на основы. Я прокомментировал код в соответствии с моим пониманием, но кто-то, пожалуйста, объясните мне более подробно о том, как все работает под капотом.

window.onload = function (){

  var $rootElement = angular.element(window.document);
  var modules = [
    'ng',       // angular module
    'myApp',    // custom module
    // what are we trying to achieve here?
    function($provide){ 
        $provide.value('$rootElement',$rootElement)
    }
  ];

  var $injector = angular.injector(modules);      // one injector per application
  var $compile = $injector.get('$compile');       // Compile Service: it traverses the DOM and look for directives and  compile and return linking function. No accecess to scope
  var compositeLinkFn = $compile($rootElement);   // collection of all linking function. Here scope is getting accessed

  var $rootScope = $injector.get('$rootScope');   // Hold of the rootscope
  compositeLinkFn($rootScope);

  $rootScope.$apply();
}

Кроме того, пожалуйста, не стесняйтесь просвещать меня больше на эту тему, предлагая больше способов и улучшений.

Ответ 1

  чего мы пытаемся достичь здесь?

var modules = [
    'ng',       // angular module
    'myApp',    // custom module
    function($provide){ 
        $provide.value('$rootElement',$rootElement)
    }
  ];

Это то же самое старое внедрение зависимости, которое мы используем везде в angularjs. Здесь мы вводим модуль ng и регистрируем в нем значение value.

И, наконец, мы передаем его в angular.injector()

  var $injector = angular.injector(modules)

Все еще не убежден? Здесь более простая версия (как мы используем DI в контроллерах)

var $injector = angular.injector(['ng','myApp',function($provide){
    $provide.value('$rootElement',$rootElement)
}])

Теперь два вопроса,

  1. почему мы используем angular.injector?

    Потому что angular.injector создает объект-инжектор, который можно использовать для извлечения служб, а также для внедрения зависимости. Нам понадобится это, чтобы получить сервис $ compile и экземпляр области видимости, с которым этот шаблон связывается.

  2. почему мы устанавливаем $rootElement?

    Чтобы angular знал корневой элемент приложения. Заметили использование document в angular.bootstrap(document,['myapp'])? Это по той же причине.

    Согласно официальной документации $ rootElement,

    $ rootElement - это либо элемент, где было объявлено ngApp, либо элемент передается в angular.bootstrap.

    Поскольку мы не используем ни ng-app, ни стандартный метод angular.bootstrap, мы должны установить это вручную.

Затем мы пытаемся получить услугу $compile из экземпляра инжектора, который мы только что получили на шаге выше.

var $compile = $injector.get('$compile');

Служба $ compile - это служба, используемая для компиляции. Вызов $ compile для разметки создаст функцию, которую вы можете использовать для привязки разметки к определенной области (то, что Angular вызывает функцию связывания)

Опять же, чтобы получить область, мы используем $injector.get('$rootScope') и передаем его в функцию составной ссылки, которую мы получили из $ compile.

angular.bootstrap(document,[myApp]) - это просто синтаксический признак вышеупомянутых шагов. Он создает экземпляр инжектора, с помощью него устанавливает соответствующие службы, создает область действия приложения и, наконец, компилирует шаблон.

Это видно из официальной документации для angular.bootstrap, в которой четко указано, что он возвращает экземпляр инжектора.

auto. $ инжектор Возвращает вновь созданный инжектор для этого приложения

Та же история указана в официальном руководстве по загрузке

Обратите внимание, что мы предоставили имя нашего модуля приложения для загрузки в инжектор как второй параметр angular.bootstrap функция. Обратите внимание, что angular.bootstrap не будет создавать модули на летать. Вы должны создать любые пользовательские модули, прежде чем передать их как параметр.

И, наконец, само собой разумеется... все это должно быть сделано после загрузки HTML-документа и готовности DOM.

EDIT

Вот схематичное представление этого процесса. angular.bootstrap process
(источник: dotnet-tricks.com)

Ссылка на изображение

Надеюсь, это поможет :)