angularInit - acelan86/angular GitHub Wiki

angularInit,初始化方法

angularInit方法是整个angular应用的初始化入口,在DOMContentLoaded的时候被执行。

/**
 * 初始化方法做了下面的事情:
 * 1. 找到ng-app元素appElement
 * 2. 获取app的入口模块名module
 * 3. 使用appElement, [module]为参数调用执行引导程序
 */
function angularInit(element, bootstrap) {
  var elements = [element],
      appElement,
      module,
      names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
      NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;

  function append(element) {
    element && elements.push(element);
  }
  //#1
  forEach(names, function(name) {
    names[name] = true;
    append(document.getElementById(name));
    name = name.replace(':', '\\:');
    if (element.querySelectorAll) {
      forEach(element.querySelectorAll('.' + name), append);
      forEach(element.querySelectorAll('.' + name + '\\:'), append);
      forEach(element.querySelectorAll('[' + name + ']'), append);
    }
  });

 //#2
  forEach(elements, function(element) {
    if (!appElement) {
      var className = ' ' + element.className + ' ';
      var match = NG_APP_CLASS_REGEXP.exec(className);
      if (match) {
        appElement = element;
        module = (match[2] || '').replace(/\s+/g, ',');
      } else {
        forEach(element.attributes, function(attr) {
          if (!appElement && names[attr.name]) {
            appElement = element;
            module = attr.value;
          }
        });
      }
    }
  });

  //#3
  if (appElement) {
    //对拥有ng-app的元素,初始模块进行引导
    bootstrap(appElement, module ? [module] : []);
  }
}

bootstrap引导程序

根据官网资料描述,引导程序做了下面几件重要的事情:

* 注入器(injector)将用于创建此应用程序的依赖注入(dependency injection);

  • 注入器将会创建根作用域作为我们应用模型的范围;
  • AngularJS将会链接根作用域中的DOM,从用ngApp标记的HTML标签开始,逐步处理DOM中指令和绑定。
function bootstrap(element, modules) {
  /* 
   * 其他的部分先忽略,引导程序的主要部分在resumeBootstrapInternal这块, 这个方法完成了下面几件事情:
   * 1. 
   */ 
  var resumeBootstrapInternal = function() {
    element = jqLite(element);
    modules = modules || [];
    modules.unshift(['$provide', function($provide) {
      $provide.value('$rootElement', element);
    }]);
    modules.unshift('ng');

    //modules = ['ng', ['$provide', fn], [modules]];
    //创建整个app的注入器
    var injector = createInjector(modules);

    injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
      function(scope, element, compile, injector) {
        scope.$apply(function() {
          element.data('$injector', injector);
          compile(element)(scope);
        });
      }]
    );
    return injector;
  };



  //var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;

  if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
    return resumeBootstrapInternal();
  }

  //window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
  //angular.resumeBootstrap = function(extraModules) {
  //  forEach(extraModules, function(module) {
  //  modules.push(module);
  //});
  //resumeBootstrapInternal();
  //};
}