angular执行图:
jquery启动:
js dom元素绑定相应的事件,当dom监听到相应的事件,这时就开始执行注册的这个事件.
angularjs执行:
首先,绑定jquery,判断是否引入jquery,如果没有引入jquery,自己会实现一个jqlit。
其次,publishExternalApi
2,publishExternalApi 在启动angular之前首要准备好service,directives...,首先在angular上注册forEach,bind方法
比如:
2.1需要备案,能够是angular能方便找到你,yourName就是检索
[]就是依赖
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...,然后这些技能都需要取个名字...
var APP = angular.module('yourName',[],configFn)
app.controller(xx)
factory()...
service()...
...
angular.module(name, [requires], [configFn]);
name:字符串类型,代表模块的名称;
requires:字符串的数组,代表该模块依赖的其他模块列表,如果不依赖其他模块,用空数组即可;
configFn:用来对该模块进行一些配置。
2.3,有了技能之后要让人知道,所以要暴露你的技能让别人来用.
如在services.js里面setupModuleLoader在angular上注册module,controller等api最后返回的是:
return(moduleInstance=(_invokeQueue:[],_runBlocks:[],controller factory service...))
2.4,有了技能,别人也已经知道了,然后也准备好了让别人调用了,首先别人需要遍历你的技能,把所有的技能都列在一个list invokeQueue上
moduleInstance={_invokeQueue _runBlock}
2.5,技能都掌握在一个人的手里,他的名字叫ng,下面就是ng的备案:
angularModule('ng',['ngLocal'],['$provide',function ngModule($provide){//ngLocal是ng自己不会的技能,所以要依赖于别人
$provide.provider('$compile',$compileProvider).directive({//compile服务是ng自己的技能
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,这个由无名氏掌握(放在匿名的空间里)
modules=[
'ng',['$provide',function($provide){$provide.value('$rootElement',element);
}],'myApp'
]
3.2 所有的技能都调集起来了现在开始决斗了,首先调用createInjecter,这里我们定义2个技能的集合:
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){
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
});
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。