angular执行图:
jquery启动:
js dom元素绑定相应的事件,当dom监听到相应的事件,这时就开始执行注册的这个事件.
angularjs执行:
首先,绑定jquery,判断是否引入jquery,若是没有引入jquery,本身会实现一个jqlit。
其次,publishExternalApi
2,publishExternalApi 在启动angular以前首要准备好service,directives...,首先在angular上注册forEach,bind方法
好比:
2.1须要备案,可以是angular能方便找到你,yourName就是检索
[]就是依赖css
var APP = angular.module('yourName',[],configFn) angular.module()建立、获取、注册angular中的模块
传递参数不止一个,表明新建模块;空数组表明该模块不依赖其余模块 var createModule = angular.module("myModule", []); 只有一个参数(模块名),表明获取模块,若是模块不存在,angular框架会抛异常 var getModule = angular.module("myModule"); getModule ==createModule
configFn就是你出生的时候能够作些初始化之类的动做,好比娃娃大叫...
2.2,出生以后能够有不少的技能,好比会angular编程,会java...,而后这些技能都须要取个名字...html
var APP = angular.module('yourName',[],configFn) app.controller(xx) factory()... service()... ...
angular.module(name, [requires], [configFn]); name:字符串类型,表明模块的名称; requires:字符串的数组,表明该模块依赖的其余模块列表,若是不依赖其余模块,用空数组便可; configFn:用来对该模块进行一些配置。
2.3,有了技能以后要让人知道,因此要暴露你的技能让别人来用.java
如在services.js里面setupModuleLoader在angular上注册module,controller等api最后返回的是: return(moduleInstance=(_invokeQueue:[],_runBlocks:[],controller factory service...))
2.4,有了技能,别人也已经知道了,而后也准备好了让别人调用了,首先别人须要遍历你的技能,把全部的技能都列在一个list invokeQueue上jquery
moduleInstance={_invokeQueue _runBlock}
2.5,技能都掌握在一我的的手里,他的名字叫ng,下面就是ng的备案:
angularModule('ng',['ngLocal'],['$provide',function ngModule($provide){//ngLocal是ng本身不会的技能,因此要依赖于别人
$provide.provider('$compile',$compileProvider).directive({//compile服务是ng本身的技能angularjs
A:htmlDirective, input:inputDirective, ...
}).directive(ngAttributeAliasDirectives).directive(ngEventDirectives);编程
$provide.provider({ $anchorScroll:$AnchorScrollProvider, $animate:$AnimateProvider, $browser:$BrowserProvider })
}])
3,angularInit
全部的东西都准备好了,如今开始启动:2种方法启动
1),ng-app
2),跳过第一步直接 doBootstrap(element,[module])
3.1在解析html的时候,不少directives的技能都是有ng这我的掌握,因此首先要召唤出ng,另外还须要注册$rootElement,这个由无名氏掌握(放在匿名的空间里)bootstrap
modules=[ 'ng',['$provide',function($provide){$provide.value('$rootElement',element);
}],'myApp'
]
3.2 全部的技能都调集起来了如今开始决斗了,首先调用createInjecter,这里咱们定义2个技能的集合:api
createInjecter(modules) //providerCache存放全部人的技能,无论名字,只管技能 providerCache:{$provider,$injector} //若是调用过了就放在这里,方便下次寻找,若是须要新的技能就去大库里寻找 instanceCache:{$injector}
3.3 遍历每一个人的invokeQueue数组
.loadModules if:string 遍历,检索出module,遍历invokeQueue,将其技能放在定义好的库里面 var invokeArgs = invokeQueue[i], provider = providerInjecter.get(invokeArgs[0]) provider[invokeArgs[1]].apply(provider,invokeArgs[2]); if:function或Array, 直接providerInjector.invoke return runBlocks
3.4 遍历全部人的技能 遍历runBlocks
forEach(runBlocks){app
instanceInjector.invoke
}
3.5 编译全部的dom compile dom
injector.invoke(['$rootScope'...])
demo 执行顺序 4,2,3,1 var app = angular.module('demo',[]) app.controller('test',[function(){//放在providerCach里,等compile服务执行以后才执行 console.log('step1') }]) app.config('test',[function($provide){//其次是config console.log('step2') }]) app.run(function(){ console.log('step3') }) angular.element(document).ready(function(){//首先是dom ready console.log('step4') angular.bootstrap(angular.element(document),['demo']) })
4,angularjs源码解析
angular源码是一个自执行函数,当js被加载完以后,当即执行。除了最后一行.
在angular的源码中,这段代码不是自执行函数。 !window.angular.$$csp() && window.angular.element(document.head).prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{position:absolute;}</style>');
代码开始执行:
if (window.angular.bootstrap) {//判断angularjs是否是已经启动,若是已经启动了就报错WARNING: Tried to load angular more than once. //AngularJS is already loaded, so we can return here... console.log('WARNING: Tried to load angular more than once.'); return; } //try to bind to jquery now so that one can write jqLite(document).ready() //but we will rebind on bootstrap again. bindJQuery();//对jquery库进行绑定 publishExternalAPI(angular);//将angular的api扩展到angular全局函数 jqLite(document).ready(function() { angularInit(document, bootstrap);//启动angular,默认从document开始启动 });
咱们在写angularjs的时候,老是要定义全局的angular函数,好比:
var app = angular.module('app',[])
那么这个angular的全局函数从哪里来的呢?
/** @name angular */ angular = window.angular || (window.angular = {}), //若是window.angular有值就返回--> angular = window.angular //若是没有值 window.angular = {} --> angular = {} 是一个空对象。
angular 是如何调用module函数呢?
angular.module
function publishExternalAPI
extend(angular, {//extend是一个工具函数,复制的做用 'bootstrap': bootstrap, 'copy': copy, 'extend': extend, 'merge': merge, 'equals': equals, 'element': jqLite, 'forEach': forEach, 'injector': createInjector, 'noop': noop, 'bind': bind, 'toJson': toJson, 'fromJson': fromJson, 'identity': identity, 'isUndefined': isUndefined, 'isDefined': isDefined, 'isString': isString, 'isFunction': isFunction, 'isObject': isObject, 'isNumber': isNumber, 'isElement': isElement, 'isArray': isArray, 'version': version, 'isDate': isDate, 'lowercase': lowercase, 'uppercase': uppercase, 'callbacks': {counter: 0}, 'getTestability': getTestability, '$$minErr': minErr, '$$csp': csp, 'reloadWithDebugInfo': reloadWithDebugInfo });