1. call anonymous function:
(function(window, document, undefined) {
...
bindJQuery();
publishExternalAPI(angular);
jqLite(document).ready(function() {
angularInit(document, bootstrap);
});
})(window, document);
1.1 jqLite(document).ready() will trigger below
var JQLitePrototype = JQLite.prototype = {
ready: function(fn) { // fn=angularInit(document, bootstrap);
var fired = false;
function trigger() {
if (fired) return;
fired = true;
fn();
}
// check if document already is loaded
if (document.readyState === 'complete'){
setTimeout(trigger);
} else {
this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9
// we can not use jqLite since we are not done loading and jQuery could be loaded later.
// jshint -W064
JQLite(window).on('load', trigger); // fallback to window.onload for others
// jshint +W064
}
2. call bindJQuery();
3. call publishExternalAPI(angular);
3.1. call extend() to put public function into angular object, so that these functions can be called in anywhere with <script></script>, e.g. angular.copy(), angular.equals()
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, 'version': version, 'isDate': isDate,'lowercase': lowercase, 'uppercase': uppercase,'callbacks': {counter: 0}, '$$minErr': minErr,
'$$csp': csp
});
3.2. call setupModuleLoade(window)
angularModule = setupModuleLoader(window);
3.2.1 put angular object into window object by ensure(), so that angular object can be use in anywhere script
function ensure(obj, name, factory) {
return obj[name] || (obj[name] = factory());
}
var angular = ensure(window, 'angular', Object);
3.2.2 put a function named as 'module' into angular ane implement code in function() { ...}, so that we can call angular.module() in anywhere java script, e.g. var phonecatApp = angular.module('phonecatApp', ['phonecatControllers']);
return ensure(angular, 'module', function() {
...
var moduleInstance = {
_invokeQueue: invokeQueue,
_runBlocks: runBlocks,
...
}
return moduleInstance // eg. var phonecatApp = angular.module('phonecatApp', ['phonecatControllers']) which equals moduleInstance
}
3.2.3 set ngLocal and ng module
angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
result: modules.put('ngLocale') -> ngLocal object includes all moduel function and var.
_invokeQueue = [$provide,provider,[object Arguments]] -> it will be execute by load bootstrap()->createInjector()->loadModules()
[object Arguments] = {['$locale', $LocaleProvider]}
$LocaleProvider = function $LocaleProvider(){}
_runBlocks = []
// angularModule(module,required, configFn)
//configFn will call invokeLater('$injector', 'invoke');
angularModule('ng', ['ngLocale'], ['$provide', function ngModule($provide) {...}]);
result: modules.push('ng') -> ng object includes all moduel function and var.
_invokeQueue = [$injector,invoke,[object Arguments]]
[object Arguments]=['$provide', function ngModule($provide) {...}]
_runBlocks = []-> it will be execute by load bootstrap()->createInjector()->loadModules()
modules = ['ng','ngLocal']
3.2.4 set app moduel in defined script
var app = angular.module('app', []);
app.controller('controller', ['$scope','$log', controller]);
app.factory('sharedService', function($rootScope) {
var sharedService = {};
sharedService.message = '';
sharedService.prepForBroadcast = function(msg) {
this.message = msg;
this.broadcastItem();
};
sharedService.broadcastItem = function() {
$rootScope.$broadcast('myEvent');
};
return sharedService;
});
app.controller('ControllerOne', ['$scope', 'sharedService',ControllerOne]);
app.controller('ControllerTwo', ['$scope', 'sharedService',ControllerTwo]);
function ControllerOne($scope, sharedService) {
$scope.handleClick = function(msg) {
sharedService.prepForBroadcast(msg);
};
$scope.$on('myEvent', function() {
$scope.message = 'ONE: ' + sharedService.message;
});
}
function ControllerTwo($scope, sharedService) {
$scope.$on('myEvent', function() {
$scope.message = 'TWO: ' + sharedService.message;
});
}
app.directive('myComponent', function(sharedService) {
return {
restrict: 'E',
controller: function($scope, $attrs, sharedService) {
$scope.$on('myEvent', function() {
$scope.message = 'Directive: ' + sharedService.message
});
},
replace: false,
template: '<input>'
};
});
4. call angularInit()
jqLite(document).ready(function() {
angularInit(document, bootstrap); // will find the element with attribute "ng-app='XXXX'" , if found, exec 4.1
});
4.1 call bootstrap(appElement, module ? [module] : []); // bootstrap(appElement,'app') -- ng-app='app'
4.1.1 var doBootstrap = function() {..}
set modules's value to [ng,$provide,function($provide) { $provide.value('$rootElement', element); },app]
4.1.2. var injector = createInjector(modules);
set below 4 variables : providerCache, providerInjector, instanceCache, instanceInjector
4.1.3 call loadModules(modules) -> will run modules['ng','ngLocal']'s _invokeQueue's function and _runBlocks's function
modules.put('ngLocale') -> ngLocal object includes all moduel function and var.
_invokeQueue = [$provide,provider,[object Arguments]]
[object Arguments] = {['$locale', $LocaleProvider]}
$LocaleProvider = function $LocaleProvider(){}
_runBlocks = []
modules.push('ng') -> ng object includes all moduel function and var.
_invokeQueue = [$injector,invoke,[object Arguments]]
[object Arguments]=['$provide', function ngModule($provide) {...}]
_runBlocks = []
function ngModule($provide) {
// $$sanitizeUriProvider needs to be before $compileProvider as it is used by it.
$provide.provider({
$$sanitizeUri: $$SanitizeUriProvider
});
$provide.provider('$compile', $CompileProvider) will return compileProvider object like as below:
function: $LocaleProvider, $$SanitizeUriProvider and $CompileProvider are executed and put it into providerCache
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,
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,
required: requiredDirective,
ngRequired: requiredDirective,
ngValue: ngValueDirective
}).
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,
$sce: $SceProvider,
$sceDelegate: $SceDelegateProvider,
$sniffer: $SnifferProvider,
$templateCache: $TemplateCacheProvider,
$timeout: $TimeoutProvider,
$window: $WindowProvider
});
}
]);
the $provide is refer to providerCahe.$provide.
providerCache = {
$provide: {
provider: supportObject(provider),
factory: supportObject(factory),
service: supportObject(service),
value: supportObject(value),
constant: supportObject(constant),
decorator: decorator
}
}
below functions are executed and put it into providerCahe.
to be continued
-----------