AngularJS-源码阅读(七)

现在开始看module的初始化。

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;
      };
    }
  });
};

});

总结一下,就是返回module创建函数,这个函数会创建module实例以及注入controller、directive、factory等。

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注入内置的函数。并命名为ngmodule。

你可能感兴趣的:(AngularJS-源码阅读(七))