本文介绍了Angularjs的启动过程分析,分享给大家
启动过程(v1.3.9)
步骤一
用自执行函数的形式让整个代码在加载完成之后立即执行
in angular.js 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全局对象都有什么东西
接着,我们使用全局对象中的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.js 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; }
angular的三种启动方式
自动启动
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"; } ]);
手动启动
在没有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 - 查找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){ .... }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍Redis服务器的启动过程分析,包括了Redis服务器的启动过程分析的使用技巧和注意事项,需要的朋友参考一下 本文将通过分析代码来介绍Redis的启动过程,通过查看Redis 的启动脚本,得知Redis的启动时从Redis.c的main方法开始的。Redis启动可以分为以下几个步骤: 1.初始化Redis服务器全局配置 2.重置服务器Save参数(具体下文详解)和加载配置文件 3.初
本文向大家介绍Android Service启动过程完整分析,包括了Android Service启动过程完整分析的使用技巧和注意事项,需要的朋友参考一下 刚开始学习Service的时候以为它是一个线程的封装,也可以执行耗时操作。其实不然,Service是运行在主线程的。直接执行耗时操作是会阻塞主线程的。长时间就直接ANR了。 我们知道Service可以执行一些后台任务,是后台任务不是耗时的任务,
本文向大家介绍简要分析linux系统的启动过程,包括了简要分析linux系统的启动过程的使用技巧和注意事项,需要的朋友参考一下 接触linux系统运维已经好几年了,常常被问到linux系统启动流程问题,刚好今天有空来梳理下这个过程: 一般来说,所有的操作系统的启动流程基本就是: 总的来说,linux系统启动流程可以简单总结为以下几步: 1)开机BIOS自检,加载硬盘。 2)读取MBR,进行MBR引
bootloader启动过程 BIOS将通过读取硬盘主引导扇区到内存,并转跳到对应内存中的位置执行bootloader。bootloader完成的工作包括: 切换到保护模式,启用分段机制 读磁盘中ELF执行文件格式的ucore操作系统到内存 显示字符串信息 把控制权交给ucore操作系统 对应其工作的实现文件在lab1中的boot目录下的三个文件asm.h、bootasm.S和bootmain.c
BIOS启动过程 当计算机加电后,一般不直接执行操作系统,而是执行系统初始化软件完成基本IO初始化和引导加载功能。简单地说,系统初始化软件就是在操作系统内核运行之前运行的一段小软件。通过这段小软件,我们可以初始化硬件设备、建立系统的内存空间映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。最终引导加载程序把操作系统内核映像加载到RAM中,并将系统控制权传
显示模式初始化和进入保护模式 这一章是内核启动过程的第三部分,在前一章中,我们的内核启动过程之旅停在了对 set_video 函数的调用(这个函数定义在 main.c)。在这一章中,我们将接着上一章继续我们的内核启动之旅。在这一章你将读到下面的内容: 显示模式的初始化, 在进入保护模式之前的准备工作, 正式进入保护模式 注意 如果你对保护模式一无所知,你可以查看前一章 的相关内容。另外,你也可以查