如今开始看module
的初始化。html
function setupModuleLoader(window) {//初始化angular以及和angular捆绑的第一个module var $injectorMinErr = minErr('$injector'); var ngMinErr = minErr('ng'); function ensure(obj, name, factory) { return obj[name] || (obj[name] = factory()); } var angular = ensure(window, 'angular', Object);//每个window下面只有一个angular实例的缘由 // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap //ensure(angular,'$$minErr',minErr); angular.$$minErr = angular.$$minErr || minErr; return ensure(angular, 'module', function() {//向angular写入module初始化函数 /** @type {Object.<string, angular.Module>} */ var modules = {};//记录一loadModules个angularjs下面全部的modules return function module(name, requires, configFn) { var assertNotHasOwnProperty = function(name, context) { if (name === 'hasOwnProperty') { throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); } }; assertNotHasOwnProperty(name, 'module'); if (requires && modules.hasOwnProperty(name)) { modules[name] = null;//同名时,覆盖掉老的。感受这个地方应该报错,而不是覆盖 } return ensure(modules, name, function() { 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); } /** @type {!Array.<Array.<*>>} */ var invokeQueue = []; /** @type {!Array.<Function>} */ var runBlocks = []; var config = invokeLater('$injector', 'invoke');//instanceCache.$injector = /** @type {angular.Module} */ var moduleInstance = { // Private state _invokeQueue: invokeQueue,//用来记录注入到本module实例下面的各类具体方法函数。 _runBlocks: runBlocks, requires: requires, name: name, provider: invokeLater('$provide', 'provider'),//$provide来自于上一节讲的providerCache factory: invokeLater('$provide', 'factory'), service: invokeLater('$provide', 'service'), value: invokeLater('$provide', 'value'), constant: invokeLater('$provide', 'constant', 'unshift'), animation: invokeLater('$animateProvider', 'register'), filter: invokeLater('$filterProvider', 'register'), controller: invokeLater('$controllerProvider', 'register'),//这些provider之后挑着讲解 directive: invokeLater('$compileProvider', 'directive'), config: config, run: function(block) { runBlocks.push(block); return this; } }; if (configFn) { config(configFn);//这也是为何moduleconfig为function,按代码逻辑来说它是支持注入的,但因为加载顺序,只能注入requires module里的attr } return moduleInstance; /** * @param {string} provider * @param {string} method * @param {String=} insertMethod * @returns {angular.Module} * 延迟加载 */ function invokeLater(provider, method, insertMethod) { return function() { invokeQueue[insertMethod || 'push']([provider, method, arguments]); return moduleInstance; }; } }); };
});angularjs
总结一下,就是返回module建立函数,这个函数会建立module实例以及注入controller、directive、factory等。bootstrap
var angularModule = setupModuleLoader(window); try { angularModule('ngLocale'); } catch (e) { angularModule('ngLocale', []).provider('$locale', $LocaleProvider);//$LocaleProvider记录默认日期分隔符等信息 //这个地方,感受没必要要try catch ,直接angularModule('ngLocale', []).provider('$locale', $LocaleProvider);。前提是 module(name)name屡次相同时,报错。 } angularModule('ng', ['ngLocale'], ['$provide', function ngModule($provide) { // $$sanitizeUriProvider needs to be before $compileProvider as it is used by it. $provide.provider({ $$sanitizeUri: $$SanitizeUriProvider//格式化Uri }); //$CompileProvider的源码1500行+。这里不讲 $provide.provider('$compile', $CompileProvider). directive({ a: htmlAnchorDirective, ...//各类内置directive的注入。之后挑着讲 }); ...//依旧是directive 的注入 $provide.provider({ $anchorScroll: $AnchorScrollProvider, ...//provider的注入,之后挑着讲 }); } ]); }
为module注入内置的函数。并命名为ng
module。ide