源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Angularjs的启动过程分析

  • 时间:2022-01-13 00:16 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Angularjs的启动过程分析
本文介绍了Angularjs的启动过程分析,分享给大家 [b]启动过程(v1.3.9)[/b] [b]步骤一[/b] 用自执行函数的形式让整个代码在加载完成之后立即执行 in [code]angular.js [/code]Line6
(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全局对象都有什么东西 [img]http://files.jb51.net/file_images/article/201707/2017071811451011.png[/img] 接着,我们使用全局对象中的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 [img]http://files.jb51.net/file_images/article/201707/2017071811451112.png[/img] 我们再来看看injector里都有什么
 /**
  * angular.injector();
  */
 var injector = angular.injector();
 console.log(injector);
一共有5个方法 annotate:分析函数签名(不要new的原因) [img]http://files.jb51.net/file_images/article/201707/2017071811451213.png[/img] [b]步骤二[/b] 检查是不是多次导入Angular:window.angular.bootstrap(通过检查指定的元素上是否已经存在injector进行判断) in [code]angular.js[/code] line 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;
   }
[b]angular的三种启动方式[/b] [b]自动启动[/b] Angular会自动的找到ng-app,将它作为启动点,自动启动
 <!DOCTYPE html>
 <html ng-app="myModule">

 <head>
   <title>New Page</title>
   <meta charset="utf-8" />
   <script type="text/javascript" src="../../vendor/bower_components/angular/angular.min.js"></script>
   <script type="text/javascript" src="./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";
   }
 ]);
[b]手动启动[/b] 在没有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']);
 });

[b]多个ng-app[/b] 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']);
 });

[b]步骤三[/b] 尝试绑定jQuery,如果发现导入了jQuery ,则使用导入的jQuery,否则,使用Angular自己封装的JQLite in[code] angular.js [/code]line 1521:
bindJQuery();
in [code]angular.js [/code]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";
  }
]);
查看执行流程 [img]http://files.jb51.net/file_images/article/201707/2017071811451314.gif[/img] [b]步骤四[/b] 发布ng提供的API in [code]angular.js [/code]line 2162 : publishExternalAPI(angular);
//构建模块加载器
angularModule = setupModuleLoader(window);
 try {
  angularModule('ngLocale');
 } catch (e) {
  angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
 }
模块加载器的实现原理 in [code]angular.js [/code]function [code]setupModuleLoader(window)[/code]
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);

查看控制台 [img]http://files.jb51.net/file_images/article/201707/2017071811451315.png[/img] 构建内置模块ng in [code]angular.js [/code]line 2169 [code]publishExternalAPI(angular)[/code]
 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:两个最重要的[code]$parser [/code]和 [code]$rootScope[/code] [b]总结[/b] [list=1] [*]工具函数拷贝到angular全局对象上;[/*] [*]调用setupModuleLoader方法创建模块定义和加载工具(挂在全局对象window.angular上);[/*] [*]构建内置模块ng;[/*] [*]创建ng内置的directive和provider;[/*] [*]两个重要的provider:$parse 和 $rootScope;[/*] [/list] [b]步骤五[/b] 初始化Angular - 查找Ng-app
 jqLite(document).ready(function() {
  angularInit(document, bootstrap);
 });
bootstrap 创建injector,拉起内核和启动模块,调用compile服务(一个ng-app只有一个injector) in [code]angular.js [/code]line 1415
function bootstrap(element, modules, config){
....
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程素材网。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部