解读AngularJS的setupModuleLoader函数

http://www.cnblogs.com/whitewolf/p/angular-module-declare-and-get.html

看了上面这篇文章,自己读了一下代码,以下是个人理解,如有请指正

/**
 * Created by Administrator on 2016/10/15.
 */
function setupModuleLoader(window) {
    //...省略部分代码

    //注意angular.module('name',[require])为定义并获取一个新的模块
    //而anguular.module('name')为获取一个已存在的模块

    //判断对象obj是否存在name属性,存在则直接返回name,否则调用函数factory设置该属性,并返回该属性
    function ensure(obj, name, factory) {
        return obj[name] || (obj[name] = factory());
    }
    //确保window对象下存在angular属性
    var angular = ensure(window, 'angular', Object);
    //确保angular下存在module属性
    return ensure(angular, 'module', function() {
        var modules = {};
        return function module(name, requires, configFn) {
            //如果模块名为hasOwnProperty,报错:不是有效的名字
            var assertNotHasOwnProperty = function(name, context) {
                if (name === 'hasOwnProperty') {
                    throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
                }
            };
            //保证模块名不是‘module’
            assertNotHasOwnProperty(name, 'module');
            //若为模块的定义,并且name与已存在的模块名重复,将原有的模块置空,即同名的模块将被后面定义的模块覆盖
            if (requires && modules.hasOwnProperty(name)) {
                modules[name] = null;
            }
            //若模块名已存在,则直接返回模块的实例,否则定义一个新模块
            return ensure(modules, name, function() {
                //要定义一个新的模块,却没有require参数,报错;注意require为[]表示定义,没有该参数表示获取
                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);
                }
                var invokeQueue = [];
                var runBlocks = [];
                var config = invokeLater('$injector', 'invoke');
                //模块实例
                var moduleInstance = {
                    _invokeQueue: invokeQueue,
                    _runBlocks: runBlocks,
                    requires: requires,
                    name: name,
                    provider: invokeLater('$provide', 'provider'),
                    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'),
                    directive: invokeLater('$compileProvider', 'directive'),
                    config: config,
                    run: function(block) {
                        runBlocks.push(block);
                        return this;
                    }
                };
                if (configFn) {
                    config(configFn);
                }
                return moduleInstance;
                //invokeLater返回一个函数,该函数在利用module创建控制器、服务等时调用,向invokeQueue中推入数据,并返回模块的实例
                //这就是为什么我们可以在angularJS中这样写
                //angular.module('someMoudule',['require1'])
                //.controller(...)
                //.directive(...)
                //而不用每次都写上模块名对应的变量名,就像下面这样
                //var myapp=angular.module(...);
                //myapp.controller(...);
                //myaap.directive(...);
                function invokeLater(provider, method, insertMethod) {
                    return function() {
                        invokeQueue[insertMethod || 'push']([provider, method, arguments]);
                        return moduleInstance;
                    };
                }
            });
        };
    });
}

 

转载于:https://www.cnblogs.com/NickCarter/p/5964605.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值