angular初始化大致上有2部分:
1.初始化angular框架,模块等
2.解析document
1.读取angular.js脚本,执行angular框架上下文脚本
(function(window, document, undefined) {
...
})(window, document);
2.初始化angular框架,配置模块,挂载angular对象
publishExternalAPI(angular);
3.使用angular框架,初始化(扫描)document中,相应的节点
angularInit(document, bootstrap);
angular源码,加载启动部分:
(function(window, document, undefined) {
//设置严格模式
'use strict';
/*********
省略代码
*********/
//尝试绑定使用jquery对象
bindJQuery();
//公布angular扩展api函数(初始化angular环境)
publishExternalAPI(angular);
//document加载完成后,加载angular
jqLite(document).ready(function() {
//加载angular入口
angularInit(document, bootstrap);
});
})(window, document);
angular源码,初始化angular框架部分
function publishExternalAPI(angular){
/********************************
设置angular公共属性,成员
********************************/
extend(angular, {
'bootstrap': bootstrap,
'copy': copy,
'extend': extend,
'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,
'$$minErr': minErr,
'version': version,
'isDate': isDate,
'lowercase': lowercase,
'uppercase': uppercase,
'callbacks': {counter: 0}
});
/********************************
创建angular默认模块
********************************/
angularModule = setupModuleLoader(window);
/********************************
尝试挂载ngLocale模块
********************************/
try {
angularModule('ngLocale');
} catch (e) {
angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
}
/********************************
配置ng模块
********************************/
angularModule('ng', ['ngLocale'], ['$provide',
function ngModule($provide) {
$provide.provider('$compile', $CompileProvider).
directive({
a: htmlAnchorDirective,
input: inputDirective,
textarea: inputDirective,
form: formDirective,
script: scriptDirective,
select: selectDirective,
style: styleDirective,
option: optionDirective,
ngBind: ngBindDirective,
ngBindHtml: ngBindHtmlDirective,
ngBindTemplate: ngBindTemplateDirective,
ngClass: ngClassDirective,
ngClassEven: ngClassEvenDirective,
ngClassOdd: ngClassOddDirective,
ngCsp: ngCspDirective,
ngCloak: ngCloakDirective,
ngController: ngControllerDirective,
ngForm: ngFormDirective,
ngHide: ngHideDirective,
ngIf: ngIfDirective,
ngInclude: ngIncludeDirective,
ngInit: ngInitDirective,
ngNonBindable: ngNonBindableDirective,
ngPluralize: ngPluralizeDirective,
ngRepeat: ngRepeatDirective,
ngShow: ngShowDirective,
ngStyle: ngStyleDirective,
ngSwitch: ngSwitchDirective,
ngSwitchWhen: ngSwitchWhenDirective,
ngSwitchDefault: ngSwitchDefaultDirective,
ngOptions: ngOptionsDirective,
ngTransclude: ngTranscludeDirective,
ngModel: ngModelDirective,
ngList: ngListDirective,
ngChange: ngChangeDirective,
required: requiredDirective,
ngRequired: requiredDirective,
ngValue: ngValueDirective
}).
directive(ngAttributeAliasDirectives).
directive(ngEventDirectives);
$provide.provider({
$anchorScroll: $AnchorScrollProvider,
$animate: $AnimateProvider,
$browser: $BrowserProvider,
$cacheFactory: $CacheFactoryProvider,
$controller: $ControllerProvider,
$document: $DocumentProvider,
$exceptionHandler: $ExceptionHandlerProvider,
$filter: $FilterProvider,
$interpolate: $InterpolateProvider,
$http: $HttpProvider,
$httpBackend: $HttpBackendProvider,
$location: $LocationProvider,
$log: $LogProvider,
$parse: $ParseProvider,
$rootScope: $RootScopeProvider,
$q: $QProvider,
$sce: $SceProvider,
$sceDelegate: $SceDelegateProvider,
$sniffer: $SnifferProvider,
$templateCache: $TemplateCacheProvider,
$timeout: $TimeoutProvider,
$window: $WindowProvider,
$$urlUtils: $$UrlUtilsProvider
});
}
]);
}
angular源码,装载angular及module部分
function setupModuleLoader(window) {
function ensure(obj, name, factory) {
return obj[name] || (obj[name] = factory());
}
/**********************************
声明window的angular属性
声明angular的module属性
注:angular.module设置为return的module函数
*********************************/
return ensure(ensure(window, 'angular', Object), 'module', function() {
var modules = {};
/**********************************
module函数
*********************************/
return function module(name, requires, configFn) {
/*******.
省略代码
*******/
});
});
}
angular源码,入口(angularInit)部分:
function angularInit(element, bootstrap) {
//检索加载angular的dom元素列表
var elements = [element],
//加载angular的dom元素
appElement,
//加载的模块
module,
//检索angular加载的关键字
names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
//提取angular加载模块的正则表达式
NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
//追加加载angular的dom元素
function append(element) {
element && elements.push(element);
}
/**********************************************************************
遍历angular加载的关键字
检索分为两种方式:
1.使用document.getElementById,检索id中关键字
2.使用element.querySelectorAll,参考:http://www.w3.org/TR/selectors-api/]
**********************************************************************/
forEach(names, function(name) {
names[name] = true;
append(document.getElementById(name));
name = name.replace(':', '\\:');
if (element.querySelectorAll) {
forEach(element.querySelectorAll('.' + name), append);
forEach(element.querySelectorAll('.' + name + '\\:'), append);
forEach(element.querySelectorAll('[' + name + ']'), append);
}
});
/**********************************************************************
解析加载angular的dom元素及module
解析分为两种方式:
1.获取element.className,提取元素class属性内容,作为module名
2.获取names中存在于dom元素上的属性,提取属性内容,作为module
**********************************************************************/
forEach(elements, function(element) {
if (!appElement) {
var className = ' ' + element.className + ' ';
var match = NG_APP_CLASS_REGEXP.exec(className);
if (match) {
appElement = element;
module = (match[2] || '').replace(/\s+/g, ',');
} else {
forEach(element.attributes, function(attr) {
if (!appElement && names[attr.name]) {
appElement = element;
module = attr.value;
}
});
}
}
});
//如果存在需要加载angular的dom元素,调用bootstrap引导加载appElement,module
if (appElement) {
bootstrap(appElement, module ? [module] : []);
}
}