启动过程

 

 

 第3部分:

1.var angular = window.angular || (window.angular = {})

2.

if (window.angular.bootstrap) {

//AngularJS is already loaded, so we can return here...
console.log('WARNING: Tried to load angular more than once.');
return;
}

3. bindJQuery();

 

3.1.  if (jQuery && jQuery.fn.on) 

yes:

no:jqLite = JQLite;

3.2. jqLite = JQLite;

4.

publishExternalAPI(angular);

4.1.

extend(angular, {
'bootstrap': bootstrap,
'copy': copy,

4.2. angularModule = setupModuleLoader(window);

 

 ensure:

function ensure(obj, name, factory) {
if (obj[name]) {
return obj[name];
} else {
return obj[name] = factory();
}
}

第一层 :

1.var modules = {}; 2.

return function module(name, requires, configFn) {
//.......
};

5.  

angular.module("ngLocale", [], ["$provide", function($provide) {
var PLURAL_CATEGORY = {ZERO: "zero", ONE: "one", TWO: "two", FEW: "few", MANY: "many", OTHER: "other"};
function getDecimals(n) {

6.jqLite(document).ready(function() {

angularInit(document, bootstrap);
});

 

 

第5部分:

 

 

 从上到下分为7步:

第1步:

function module(name, requires, configFn) {
var assertNotHasOwnProperty = function(name, context) {
if (name === 'hasOwnProperty') {
throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
}
};

1.1.

var assertNotHasOwnProperty = function(name, context) {
if (name === 'hasOwnProperty') {
throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
}
};

1.2.

assertNotHasOwnProperty(name, 'module');
if (requires && modules.hasOwnProperty(name)) {
modules[name] = null;
}

1.3.

 

2.

if (!requires) {
throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
"the module name or forgot to load it. If registering a module ensure that you " +
"specify the dependencies as the second argument.", name);
}

2.1.

if (!requires) {
throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
"the module name or forgot to load it. If registering a module ensure that you " +
"specify the dependencies as the second argument.", name);
}

2.2.

/** @type {!Array.<Array.<*>>} */
var invokeQueue = [];

/** @type {!Array.<Function>} */
var configBlocks = [];

/** @type {!Array.<Function>} */
var runBlocks = [];

 

 

 2.3.var config = invokeLater('$injector', 'invoke', 'push', configBlocks);

 

 

 2.4.

/** @type {angular.Module} */
var moduleInstance = {
// Private state
_invokeQueue: invokeQueue,
_configBlocks: configBlocks,
_runBlocks: runBlocks,

_invokeQueue: invokeQueue,_configBlocks: configBlocks,_runBlocks: runBlocks,requires: requires,name: name,

provider: invokeLaterAndSetModuleName('$provide', 'provider'),

2.5.if (configFn) {config(configFn);}

2.6.return moduleInstance;

第2步:

 

 provider: invokeLaterAndSetModuleName('$provide', 'provider'),

function invokeLaterAndSetModuleName(provider, method) {
return function(recipeName, factoryFunction) {
if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
invokeQueue.push([provider, method, arguments]);
return moduleInstance;
};
}

return function(recipeName, factoryFunction) {
if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
invokeQueue.push([provider, method, arguments]);
return moduleInstance;
};

第3,4,5步:

 

 第6步:

 

 从右到左的代码:

1.var config = invokeLater('$injector', 'invoke', 'push', configBlocks);

2.function invokeLater(provider, method, insertMethod, queue) {
if (!queue) queue = invokeQueue;
return function() {
queue[insertMethod || 'push']([provider, method, arguments]);
return moduleInstance;
};}

3.return function() {

queue[insertMethod || 'push']([provider, method, arguments]);
return moduleInstance;
};

4.return function() {

queue[insertMethod || 'push']([provider, method, arguments]);
return moduleInstance;
};return function() {
queue[insertMethod || 'push']([provider, method, arguments]);
return moduleInstance;
};

第7步:

run: function(block) {
runBlocks.push(block);
return this;
}

第7部分:

 

 1.forEach(ngAttrPrefixes, function(prefix) {

var name = prefix + 'app';
var candidate;

if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
appElement = candidate;
module = candidate.getAttribute(name);
}});

2.if (appElement) {

config.strictDi = getNgAttribute(appElement, "strict-di") !== null;
bootstrap(appElement, module ? [module] : [], config);
}

 

 

核心代码:var doBootstrap = function() {
element = jqLite(element);

if (element.injector()) {

 1.if (element.injector()) {

var tag = (element[0] === document) ? 'document' : startingTag(element);
//Encode angle brackets to prevent input from being sanitized to empty string #8683
throw ngMinErr(
'btstrpd',
"App Already Bootstrapped with this Element '{0}'",
tag.replace(/</,'&lt;').replace(/>/,'&gt;'));
}

2.modules.unshift(['$provide', function($provide) {

$provide.value('$rootElement', element);
}]);

3.var injector = createInjector(modules, config.strictDi);

 

 3.1.providerCache = {

$provide: {
provider: supportObject(provider),
factory: supportObject(factory),
service: supportObject(service),
value: supportObject(value),
constant: supportObject(constant),
decorator: decorator
}
},

3.2.providerInjector = (providerCache.$injector =

createInternalInjector(providerCache, function(serviceName, caller) {
if (angular.isString(caller)) {
path.push(caller);
}
throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- '));
})),

3.2.2.function createInternalInjector(cache, factory) {

function getService(serviceName, caller) {
if (cache.hasOwnProperty(serviceName)) {

3.3.instanceCache = {},

3.4.instanceCache = {},

instanceInjector = (instanceCache.$injector =
createInternalInjector(instanceCache, function(serviceName, caller) {
var provider = providerInjector.get(serviceName + providerSuffix, caller);
return instanceInjector.invoke(provider.$get, provider, undefined, serviceName);
}));

 

 3.5.forEach(loadModules(modulesToLoad), function(fn) { if (fn) instanceInjector.invoke(fn); });

3.5.1.

 

 1.1.if (loadedModules.get(module)) return;

loadedModules.put(module, true);

1.2.if (isString(module)) {

moduleFn = angularModule(module);
runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);
runInvokeQueue(moduleFn._invokeQueue);
runInvokeQueue(moduleFn._configBlocks);
}

 

1.2.1.moduleFn = angularModule(module);

1.2.2.loadModules(moduleFn.requires)

1.2.3.runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks);

1.3. else if (isFunction(module)) {

runBlocks.push(providerInjector.invoke(module));
} else if (isArray(module)) {
runBlocks.push(providerInjector.invoke(module));
}

 

4. 

injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
function bootstrapApply(scope, element, compile, injector) {
scope.$apply(function() {
element.data('$injector', injector);
compile(element)(scope);
});
}]
);

function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective,
previousCompileContext) {
if (!($compileNodes instanceof jqLite)) {

4.1.var compositeLinkFn =

compileNodes($compileNodes, transcludeFn, $compileNodes,
maxPriority, ignoreDirective, previousCompileContext);

 

 1.1.directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined,

ignoreDirective);

1.2.childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||

!(childNodes = nodeList[i].childNodes) ||
!childNodes.length)
? null
: compileNodes(childNodes,

1.3.if (nodeLinkFn || childLinkFn) {

linkFns.push(i, nodeLinkFn, childLinkFn);
linkFnFound = true;
nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn;
}

4.2.

unction compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {
var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn;
var stableNodeList;

4.2.1.controllerScope = scope;

if (newIsolateScopeDirective) {
isolateScope = scope.$new(true);
} else if (newScopeDirective) {
controllerScope = scope.$parent;}

4.2.2.// Initialize bindToController bindings

for (var name in elementControllers) {
var controllerDirective = controllerDirectives[name];
var controller = elementControllers[name];
var bindings = controllerDirective.$$bindings.bindToController;

4.2.3.// POSTLINKING

for (i = postLinkFns.length - 1; i >= 0; i--) {
linkFn = postLinkFns[i];
invokeLinkFn(linkFn,
linkFn.isolateScope ? isolateScope : scope,
$element,

 

posted @ 2019-09-25 17:48  onyli  阅读(194)  评论(0)    收藏  举报