• AngularJs依赖注入原理


    什么是依赖注入?将一个或多个依赖(或服务)注入到一个独立的对象中。
    在angular中,provider、factory、service、value、constant可以用于注入,控制器和工厂方法(指令、服务、过滤器)可接受注入。
    当应用(app)引导启动时,angular生成一个注入器,用于寻找并注入app中所有引入的服务(例如,$http、$route)。
    下面是依赖注入的简单实现:
    var DI = {
        /**
         * 保存能够被注入的服务
         */
        providerCache: {},
        /**
         * 注册一个新的服务时,以key: value形式保存在providerCache map中
         * @param key
         * @param value
         */
        register: function (key, value) {
            this.providerCache[key] = value;
        },
        /**
         * 实现依赖注入
         * @param fn
         * @param self
         * @returns {*}
         */
        inject: function (fn, self) {
            var $inject = this.annotate(fn), //获得函数的参数(被注入的对象key值)
                args = [];
    
            //遍历providerCache获得所有注入的对象,用一个数组记录
            for (var i = 0, len = $inject.length; i < len; i++) {
                args.push(this.providerCache[$inject[i]]);
            }
            if (isArray(fn)) {
                fn = fn[len];
            }
            //注入
            return fn.apply(self, args);
        },
        /**
         * 提取函数的参数
         * @param fn
         * @returns {Array}
         */
        annotate: function (fn) {
            var fnString = fn.toString(),
                args = [],
                FUNC_ARGS = /^function\s*[^(]*\(\s*([^)]*)\s*\)/m,
                FUNC_ARG_SPLIT = /,\s*/;
            if (isFunction(fn)) {
                args = fnString.match(FUNC_ARGS)[1].split(FUNC_ARG_SPLIT);
            }
            else if (isArray(fn)) {
                args = fn.slice(0, fn.length - 1);
            }
            return args;
        }
    }
    
    function isFunction(fn) {
        return typeof fn === 'function';
    }
    function isArray(arr) {
        return Object.prototype.toString.call(arr) === '[object Array]';
    }
    可运行例子:
    /**
     * provider定义方法
     * @param name
     * @param fn
     */
    function registerProvider(name, fn) {
        var obj = DI.inject(fn);
        DI.register(name, obj);
    }
    
    /**
     * controller定义方法
     * @param name
     * @param fn
     */
    function registerController(name, fn) {
        DI.inject(fn);
    }
    
    
    registerProvider('provider1', function () {
        return {
            provider1: 'foo'
        }
    })
    
    registerProvider('provider2', function (provider1) {
        return {
            provider2: provider1.provider1 + ' bar'
        }
    })
    
    registerController('controller', ['provider2', function (provider2) {
        console.log(provider2.provider2);
    }])

    AngularJs中,注入器是在angular启动时生成的,源码中,angular启动函数(bootstrap)中,代码:

    var injector = createInjector(modules);

    生成了一个注入器,注入器的具体实现可查看源码createInjector函数。

  • 相关阅读:
    CentOS7虚拟机安装Linux教程及安装后所遇到的问题
    华为测试用例模板简写
    python字符串大小写转换
    python解释器的下载和安装
    Git安装和常用命令
    python保留两位小数
    python中list的使用
    安装Maven及Eclipse中配置Maven
    伪静态技术
    CI框架两个application共用同一套 model
  • 原文地址:https://www.cnblogs.com/zmiaozzz/p/6510352.html
Copyright © 2020-2023  润新知