如来神掌 - 玩转 AngualrJS 的依赖注入

先了解依赖

首先咱们要了解什么是依赖;举个例子吧,好比你玩撸啊撸,你看到别人在玩小提莫,你以为挺好玩,也想玩这个英雄,那么你就要去商店把这个英雄买下来,而后才可使用这个英雄,拥有这个英雄就是你的依赖;简单的说,依赖就是你达到某个目的的必要条件。javascript

依赖注入是一种软件的设计模式,它容许你移除软件组件之间的硬编码方式,替代的是经过依赖注入制造低耦合的组件不管是在编译阶段仍是在运行阶段。html

AngularJS有一个内在的依赖注入机制,使用AngularJS,你能够把你的App分红许多个能够重复使用的组件,当须要这些组件的时候,能够经过依赖注入把这些组件注入到你的App中去。java

得到对依赖的控制权

一般一个对象有三种方法能够得到对其依赖的控制权设计模式

  1. 在内部建立依赖:这种方法的弊端就是不方便之后的维护,使隔离变的异常困难。数组

  2. 经过全局变量进行引用:这种方法的弊端就是污染了全局做用域,当代码量达到了必定程度后,容易出现问题。app

  3. 在须要的地方进行参数传递:这种方法不只对测试颇有用,并且不会污染全局变量,是很好的设计模式。AngularJS用的就是这种方法。函数

AngularJS依赖注入的方法

1. 经过函数的参数进行推断式注入声明

若是没有明确的声明,AngularJS会假定参数名称就是依赖的名称。所以,它会在内部调用函数对象的toString()方法,分析并提取出函数的参数列表,而后经过 $injector将这些参数注入进对象实例。测试

下面是代码示例:编码

HTML代码:.net

html<div ng-app>
    <div ng-controller="MyController">
        <p ng-cloak>{{clock.time | date: "yyyy-MM-dd hh:mm:ss"}}</p>
    </div>
</div>

JS代码:

javascriptfunction MyController($scope, $timeout) {
    var updateTime = function () {
        $scope.clock = {
            time: new Date()
        };
        $timeout(function () {
            $scope.clock.time = new Date();
            updateTime();
        }, 1000);
    }
    updateTime();
}

Online Code Part1

对上面代码的解释:

咱们经过上面的JS代码在HTML页面中建立了一个能够自动更新的时间,

咱们先不去关心如何实现时间更新的,先看看咱们是如何进行依赖注入的;咱们在MyController这个函数中设置的参数名称分别是$scope$timeout因此在程序运行到这个函数的时候,AngularJS会在内部调用函数对象的toString()方法,假定参数的名称就是依赖的名称,分析并提取出函数的参数列表,而后经过$injector将这些参数注入进对象的实例。

须要注意的地方:

  • 与上述方法只在AngularJS的版本低于1.3.0时才能够成功运行。
  • 这个方法只适合未通过压缩和混淆的代码,由于AngularJS须要原始未经压缩的参数列表来进行解析。

2. 显式的注入声明

AngularJS提供了显式地方法来明肯定义一个函数在被调用时须要用到的依赖关系。经过这种方法声明依赖,即便在源代码被压缩,参数名称发生改变的状况下依然能够正常工做。

下面是代码示例:

HTML代码:

html<div ng-app>
    <div ng-controller="MyController">
        <p ng-cloak>{{clock.time | date: "yyyy-MM-dd hh:mm:ss"}}</p>
    </div>
</div>

JS代码:

javascriptfunction MyController(s, t) {
    var updateTime = function () {
        s.clock = {
            time: new Date()
        };
        t(function () {
            s.clock.time = new Date();
            updateTime();
        }, 1000);
    }
    updateTime();
}
MyController["$inject"] = ["$scope", "$timeout"];

Online Code Part2

对上面代码的解释:

咱们给咱们的函数设置的参数名称分别是st,而后咱们在后面使用MyController["$inject"] = ["$scope", "$timeout"];显式的将咱们须要的依赖注入到MyController函数中;因此在MyController函数中,s表明$scope,t表明$timeout,是否是感受不像听的那么难,咱们继续咱们的依赖注入。

须要注意的地方

  • 对于这种声明方式来说,参数的顺序是十分重要的,由于$inject数组元素的顺序必须和注入的参数的顺序一一对应。

上面的JS代码还有一种写法以下所示:

JS代码:

javascriptvar MyControllerFactory = function MyController(s, t) {
    var updateTime = function () {
        s.clock = {
            time: new Date()
        };
        t(function () {
            s.clock.time = new Date();
            updateTime();
        }, 1000);
    }
    updateTime();
}
MyControllerFactory.$inject = ["$scope","$timeout"];

注意HTML代码中的ng-controller须要改成MyControllerFactory

Online Code Part3

行内注入声明

AngularJS提供的行内注入方法其实是一种语法糖,它与前面的提到的经过$inject属性进行声明的原理是同样的,可是容许咱们在函数定义的时候从行内将参数传入,这种方法方便,简单,并且避免了在定义的过程当中使用临时变量。

下面是代码示例:

HTML代码:

html<div ng-app="MyApp">
    <div ng-controller="MyController">
        <p ng-cloak>{{clock.time | date: "yyyy-MM-dd hh:mm:ss"}}</p>
    </div>
</div>

JS代码:

javascriptangular.module("MyApp", [])
.controller("MyController", ["$scope", "$timeout", function (s, t) {
    var updateTime = function () {
        s.clock = {
            time: new Date()
        };
        t(function () {
            s.clock.time = new Date();
            updateTime();
        }, 1000);
    }
    updateTime();
}]);

Online Code Part4

须要注意的地方,行内声明的方式容许咱们直接传入一个参数数组,而不是一个函数。数组的元素是字符串,它们表明的是能够被注入到对象中的依赖名字,最后一个参数就是依赖注入的目标函数对象自己。

到这里已经把AngularJS的依赖注入方法说得差很少了,不过还有一点,就是咱们上面的方法都依赖一个服务,那就是$injector,我后面会和你们一块儿来探讨一下这个东西究竟是什么东西。

还有若是你以为我上面所说的有些地方是不对的,还望指出来,咱们一块儿进步^_^

相关文章
相关标签/搜索