TAT.tennylv AngularJs 依赖注入的研究
In 未分类 on 2015年09月01日 by view: 7,974
7

什么是依赖注入呢,我的理解,简单点就是说我的东西我自己并不像来拿着,我想要我依赖的那个人来帮我拿着,当我需要的时候,他给我就行了。当然这只是简单的理解,还是用代码解释比较清楚一些。

这里有一个 function,很简单。

我们调用它:

那么,就像我上面说的,我能不能自己不传参数呢,例如:

如何才能实现让别人帮我们注入这个参数呢:

像这样,我们在定义参数的时候这样传:

我们再调用 a 方法:

这其实就是最简单的依赖注入了,当然这么简单是不行的,其实这是很无意义的,下面我们来看一下高深的 angularjs:

 

上面这段代码定义了 angularjs 的 controller 里面用到了 scope,这样还看不出问题,在看下面:

上面这段代码在原来的基础上增加了 http, 那么问题就来了,angular 在调用 controller 的时候怎么知道我需要 scope 还是 http 还是两个都需要呢,这就牵着到了 angular 里的依赖注入,那么我们来模拟一下。

假设没有 angular 的情况下,我们:

肯定会报错的,然后我们来修改下我们的 inject:

这里解释一下,我们用了 dependencies 来存储所有的依赖,register 来实现注册依赖,resolve 方法来实现注入。

然后我们模仿 angular 来预先注册几个模块:

然后我们就可以注入了:

我们只需要 http 和 scope,所以我们只传了两个,虽然这样看似解决了依赖注入,但是还有很多问题,比如我要交换两个参数的位置就不行了。

于是翻看了 angularjs 的源码,找到了:

我们忽略掉一些细节代码,只看我们需要的。annotate 方法和我们的 resolve 方法很像。它转换传递过去的 func 为字符串,删除掉注释代码,然后抽取其中的参数。让我们看下它的执行结果,修改一下 resolve 方法:

打印出 argDecl:

可以看到,这个数组拿到了 func 的参数,argDecl[1] = “$scope,$http”;

根据这个,我们来修改 resolve:

OK,这次我们不用在意参数的顺序了,但是 angular 远比我们要想的多,大多数情况下,我们的 js 都是要压缩的,所以 function 的实参会被替换,如果是那样的话,我们这个方法的 argDecl[1] = “$scope,$http”; 就会是 argDecl[1] = “r,t”; 类似这样的变量,那么又该怎么解决呢?

angular 官方有这样的解释:

为了克服压缩引起的问题,只要在控制器函数里面给 $inject 属性赋值一个依赖服务标识符的数组,就像:

那么,用到我们这个方法里面又该怎么实现呢?那我们在看看 angular 的源码吧:

看到了吧,之所以用到数组也是有原因的,把需要的依赖写在方法的前面,于是,应用到我们的 reslove 方法:

OK,到这里,便可以用我们的 inject 来模拟 angular 的依赖注入了,当然,真正 angular 的依赖注入还有很多东西,这里就不在详细描述了。

以上观点都是我的个人见解,如有错误欢迎指正!

 

参考资料:关于 anjularjs 双向绑定的研究

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2015/09/angularjs-study-of-dependency-injection/

  1. 四神info 2017 年 11 月 13 日

    var MyController = function ($scope, $http) {
    debugger;
    $scope.test = 1;
    $http.get(”);
    }
    函数参数里带空格的话,会有问题

  2. jinglf 2017 年 1 月 13 日

    分析的挺好

  3. 呆呆的阿饭 2016 年 8 月 26 日

    今天面试被问到 Angular 依赖注入的实现原理,没答上,赶紧过来看看

  4. 换个昵称 2016 年 5 月 26 日

    初学 angularjs, 循序渐进,通俗易懂。

  5. 朕还能学啊 2016 年 5 月 4 日

    ( ̄▽ ̄)” 初学 angular

  6. 缚锥共80 2015 年 10 月 29 日

    [悲伤]

  7. 刘文俊 2015 年 10 月 6 日

    也看过 angular 依赖注入的源码,不过你这种循序渐进的讲解更能让人明白它的实现思路。

发表评论