启动过程(v1.3.9)###
步骤一
- 用自执行函数的形式让整个代码在加载完成之后立即执行 
 in- angular.jsLine6- (function(window, document, undefined) 
- 在window上暴露一个唯一的全局对象angular,Line250 - angular = window.angular || (window.angular = {})
- 获得其它工具模块 Line 2129 - function publishExternalAPI(angular) { extend(angular, { 'bootstrap': bootstrap, 'copy': copy, 'extend': extend, 'equals': equals, 'element': jqLite, 'forEach': forEach, 'injector': createInjector, 'noop': noop, 'bind': bind, .....
- 我们来看看angular全局对象都有什么东西 
- 接着,我们使用全局对象中的isFunction 来遍历一下angular全局对象上的属性,函数 - var counter = 0; for (var p in angular) { counter++; if (angular.isFunction(angular[p])) { console.log("function->" + p); } else { console.log("property-->" + p + "-->" + angular[p]); } } console.log(counter);
有两个property,其它都是function
- 我们再来看看injector里都有什么 - /** * angular.injector(); */ var injector = angular.injector(); console.log(injector); 
一共有5个方法
annotate:分析函数签名(不要new的原因)
步骤二
- 检查是不是多次导入Angular:window.angular.bootstrap(通过检查指定的元素上是否已经存在injector进行判断) - in - angular.jsline 26041
      if (window.angular.bootstrap) {        //AngularJS is already loaded, so we can return here...
        console.log('WARNING: Tried to load angular more than once.');        return;
      }angular的三种启动方式
- 自动启动 - Angular会自动的找到 - ng-app,将它作为启动点,自动启动- <!DOCTYPE html> <html ng-app="myModule"> <head> <title>New Page</title> <meta charset="utf-8" /> <script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="../../vendor/bower_components/angular/angular.min.js"></script> <script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="./02.boot1.js"></script> </head> <body> <div ng-controller="MyCtrl"> <span>{{Name}}</span> </div> </body> </html>js var myModule = angular.module("myModule", []); myModule.controller('MyCtrl', ['$scope', function($scope) { $scope.Name = "Puppet"; } ]);
- 手动启动 - 在没有ng-app的情况下,只需要在js中添加一段注册代码即可 <body> <div ng-controller="MyCtrl"> <span>{{Name}}</span> </div> </body>- js - var myModule = angular.module("myModule", []); myModule.controller('MyCtrl', ['$scope', function($scope) { $scope.Name = "Puppet"; } ]); /** * 这里要用ready函数等待文档初始化完成 */ angular.element(document).ready(function() { angular.bootstrap(document, ['myModule']); });
- 多个ng-app - ng中,angular的ng-app是无法嵌套使用的,在不嵌套的情况下有多个ng-app,他默认只会启动第一个ng-app,第二个第三个需要手动启动(注意,不要手动启动第一个,虽然可以运行,但会抛异常) - <body> <div id="app1" ng-app="myModule1"> <div ng-controller="MyCtrl"> <span>{{Name}}</span> </div> </div> <div id="app2" ng-app="myModule2"> <div ng-controller="MyCtrl"> <span>{{Name}}</span> </div> </div> </body>- js - /** * 第一个APP * @type {[type]} */ var myModule1 = angular.module("myModule1", []); myModule1.controller('MyCtrl', ['$scope', function($scope) { $scope.Name = "Puppet"; } ]); // angular.element(document).ready(function() { // angular.bootstrap(app1, ['MyModule1']); // }); /** * 第二个APP * @type {[type]} */ var myModule2 = angular.module("myModule2", []); myModule2.controller('MyCtrl', ['$scope', function($scope) { $scope.Name = "Vincent"; } ]); angular.element(document).ready(function() { angular.bootstrap(app2, ['myModule2']); });
步骤三
尝试绑定jQuery,如果发现导入了jQuery ,则使用导入的jQuery,否则,使用Angular自己封装的JQLite
in angular.js line 1521:
bindJQuery();
in angular.js line 1534:
  jQuery = window.jQuery;if (jQuery && jQuery.fn.on) {
    jqLite = jQuery;
    extend(jQuery.fn, {      scope: JQLitePrototype.scope,      isolateScope: JQLitePrototype.isolateScope,      controller: JQLitePrototype.controller,      injector: JQLitePrototype.injector,      inheritedData: JQLitePrototype.inheritedData
    });测试
<html ng-app="myModule"><body>
    <div>
        <div ng-controller="MyCtrl">
            <span>{{Name}}</span>
        </div>
    </div></body></html>js
var myModule = angular.module("myModule", []);
myModule.controller('MyCtrl', ['$scope',    function($scope) {
        $scope.Name = "Puppet";
    }
]);查看执行流程
步骤四
发布ng提供的API
in angular.js line 2162 : publishExternalAPI(angular);
//构建模块加载器angularModule = setupModuleLoader(window);  try {
    angularModule('ngLocale');
  } catch (e) {
    angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
  }模块加载器的实现原理
in angular.js function setupModuleLoader(window)
function setupModuleLoader(window) {  var $injectorMinErr = minErr('$injector');  var ngMinErr = minErr('ng');  function ensure(obj, name, factory){  return obj[name] || (obj[name] = factory());
  }  var angular = ensure(window, 'angular', Object);  // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
  angular.$$minErr= angular.$ $minErr || minErr;  //把module方法放到angular的全局对象上,ensure就是一个属性拷贝的过程return ensure(angular, 'module', function(){    //模块缓存
    var modules = {};
}把工具函数给载到模块里
return function module(name, requires, configFn) {
......
}查看模块里所包含的内容
<!DOCTYPE html><html ng-app="myModule"></html>
JS
/**
 * 定义模块
 */var myModule = angular.module("myModule", []);/**
 * 从debug的过程可以看到,angular中的“模块”只是一个闭包空间(或者叫命名空间)
 * 所有模块都被注册在modules这个对象上
 */console.log(myModule);查看控制台
构建内置模块ng
in angular.js line 2169 publishExternalAPI(angular)
 angularModule('ng', ['ngLocale'], ['$provide',
    function ngModule($provide) {      // $ $sanitizeUriProvider needs to be before $compileProvider as it is used by it.
      $provide.provider({
        $ $sanitizeUri: $$SanitizeUriProvider
      });
      $provide.provider('$compile', $CompileProvider).
        directive({            a: htmlAnchorDirective,            input: inputDirective,
            ......加载了所有内置的directive,provider.注册ng内核Provider:两个最重要的$parser 和 $rootScope
总结
- 工具函数拷贝到angular全局对象上; 
- 调用setupModuleLoader方法创建模块定义和加载工具(挂在全局对象window.angular上); 
- 构建内置模块ng; 
- 创建ng内置的directive和provider; 
- 两个重要的provider:$parse 和 $rootScope; 
步骤五
初始化Angular - 查找Ng-app
  jqLite(document).ready(function() {
    angularInit(document, bootstrap);
  });bootstrap
创建injector,拉起内核和启动模块,调用compile服务
(一个ng-app只有一个injector)
in angular.js line 1415
function bootstrap(element, modules, config){
....
}
作者:易sense
链接:https://www.jianshu.com/p/d805f599fda5
共同学习,写下你的评论
评论加载中...
作者其他优质文章
 
                 
            





 
			 
					 
					