angularjs源码分析(AngularJS v1.3.0)
0---1402行
概要描述
这一部分主要定义了一些通用的函数,例如常用的字符串处理trim、lowercase、uppercase、foreach、copy、extends等等
关键分析
1、shallowCopy与copy
shallowCopy是浅copy
copy是深度copy
2、从1263--1275行代码定义了getNgAttribute方法,可以看出所以与angular相关的属性名称都是以['ng-','data-ng-','ng:','x-ng-']其中的一个为前缀,否则无效
3、从1277--1381行的注释中,可以清晰的了解到四方面的信息
1)、如何定义一个模块
varngAppDemo=angular.module('ngAppDemo',[]);
打开1734行代码
returnfunctionmodule(name,requires,configFn)
我们可以看到module方法的有三个参数:
name:模块名称
requires:依赖模块列表
configFn:主要用来配置关联的模块
具体调用如下:
varngAppDemo=angular.module('ngAppDemo',['aaa','bbbb'],function($xxService,$xxprovider){
//angular会根据function函数的参数名称自动注入对应的服务,之后我们可以通过参拿到相关
//服务的对象,接下来我们就可以配置这些对象喽
$xxService.xxMethod();
......
});
2)、如何创建Controller,以及如果将controller.$scope中的属性绑定到你的htmltemplate中。
例如:
<divng-controller="ngAppDemoController">
Icanadd:{{a}}+{{b}}={{a+b}}
</div>
1)、{{}}就是传说中的绑定神器,可以在{{}}写表达式、调用controller.$scope函数和属性
2)、创建一个controller,在angular思想当中有两个概念“模块”、“服务”。“模块“中可以包含很多
“服务”controller就是服务中的一种。
angular.module('ngAppDemo',[]).controller('ngAppDemoController',function($scope){
$scope.a=1;
$scope.b=2;
});
很神奇吧?当这段代码执行时,上面的html模板就会自动生成为:icanadd1+2=3。
3)、ng-app是什么作用。
简单点说就是标识angularrootscope的Dom作用域
4)、ng-strict-di是什么?从字面上理解:“严格执行依赖”,注释中给出的解释如下:(我会继续认证下面的结论)
angular.module('ngAppStrictDemo',[])
//BadController的定义方式在ng-strict-di模式下是错误的,因为在ng-strict-di的任何依赖都需要提前声明
//如果仅仅通过函数参数字面量上标记需要依赖的服务是错误的,所以必须要提前声明
.controller('BadController',function($scope){
$scope.a=1;
$scope.b=2;
})
//正确的
.controller('GoodController1',['$scope',function($scope){
$scope.a=1;
$scope.b=2;
}])
//正确的。因为下面多了一行GoodController2.$inject=['$scope'];
.controller('GoodController2',GoodController2);
functionGoodController2($scope){
$scope.name="World";
}
GoodController2.$inject=['$scope'];
1404~行
1、1404~1431行
定义了一个angularInit方法,从方法名称可以看出是用来初始化angularapp的,该方法会有两个参数element,bootstrap,接下来会首先查找
ng-appDom,如果element不存在ng-app,就会从childElement查找,之后会调用如下方法启动app应用:
bootstrap(appElement,module?[module]:[],config);
2、1655~1970行
采用闭包的方式定义了angular.module方法,module方法内部的逻辑是:当我们创建一个module对象时,对象内部会创建三个数组
/**@type{!Array.<Array.<*>>}*/
varinvokeQueue=[];
/**@type{!Array.<Function>}*/
varconfigBlocks=[];
/**@type{!Array.<Function>}*/
varrunBlocks=[];
例如invokeQueue中存储了模块初始化话时的调用顺序队列,也就是说,它把模块中每一个服务的初始化步骤变成队列来表示,当真正执行初始化,会自动遍历
队列执行每一个方法。
除此之外module包含了模块的名称(name)、依赖信息(requires)
3、1072~2053行
从这些注释中,可以知道接下来的代码主要是定义一些XXDirective、XXProvider,接下来的代码是angular的核心,如果我们不知道该怎么定义自己的指令Directive
或者其他服务:filter、service等等,这时可以参考下面的代码
4、2080~2109行
这些代码将会告诉你,为什么可以直接用angular.noop、angular.forEach这样的调用方式,因为继承了嘛
5、2080~2206行
这里定义一个publishExternalAPI方法,该方法业务逻辑是:创建了ngLocale、ng两个模块。ng模块依赖于nglocale,并且在ng模块中定义一个configFn:ngModule(2119行)
。哇塞!在ngModule方法内部,我们可以看到很多内置的XXDirective、XXProvider:
$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,
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,
pattern:patternDirective,
ngPattern:patternDirective,
required:requiredDirective,
ngRequired:requiredDirective,
minlength:minlengthDirective,
ngMinlength:minlengthDirective,
maxlength:maxlengthDirective,
ngMaxlength:maxlengthDirective,
ngValue:ngValueDirective,
ngModelOptions:ngModelOptionsDirective
}).
directive({
ngInclude:ngIncludeFillContentDirective
}).
directive(ngAttributeAliasDirectives).
directive(ngEventDirectives);
$provide.provider({
$anchorScroll:$AnchorScrollProvider,
$animate:$AnimateProvider,
$browser:$BrowserProvider,
$cacheFactory:$CacheFactoryProvider,
$controller:$ControllerProvider,
$document:$DocumentProvider,
$exceptionHandler:$ExceptionHandlerProvider,
$filter:$FilterProvider,
$interpolate:$InterpolateProvider,
$interval:$IntervalProvider,
$http:$HttpProvider,
$httpBackend:$HttpBackendProvider,
$location:$LocationProvider,
$log:$LogProvider,
$parse:$ParseProvider,
$rootScope:$RootScopeProvider,
$q:$QProvider,
$$q:$$QProvider,
$sce:$SceProvider,
$sceDelegate:$SceDelegateProvider,
$sniffer:$SnifferProvider,
$templateCache:$TemplateCacheProvider,
$timeout:$TimeoutProvider,
$window:$WindowProvider,
$$rAF:$$RAFProvider,
$$asyncCallback:$$AsyncCallbackProvider
});