首先咱们要了解什么是依赖;举个例子吧,好比你玩撸啊撸,你看到别人在玩小提莫,你以为挺好玩,也想玩这个英雄,那么你就要去商店把这个英雄买下来,而后才可使用这个英雄,拥有这个英雄就是你的依赖;简单的说,依赖就是你达到某个目的的必要条件。javascript
依赖注入是一种软件的设计模式,它容许你移除软件组件之间的硬编码方式,替代的是经过依赖注入制造低耦合的组件不管是在编译阶段仍是在运行阶段。html
AngularJS有一个内在的依赖注入机制,使用AngularJS,你能够把你的App分红许多个能够重复使用的组件,当须要这些组件的时候,能够经过依赖注入把这些组件注入到你的App中去。java
一般一个对象有三种方法能够得到对其依赖的控制权设计模式
在内部建立依赖:这种方法的弊端就是不方便之后的维护,使隔离变的异常困难。数组
经过全局变量进行引用:这种方法的弊端就是污染了全局做用域,当代码量达到了必定程度后,容易出现问题。app
在须要的地方进行参数传递:这种方法不只对测试颇有用,并且不会污染全局变量,是很好的设计模式。AngularJS
用的就是这种方法。函数
若是没有明确的声明,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(); }
对上面代码的解释:
咱们经过上面的JS代码在HTML页面中建立了一个能够自动更新的时间,
咱们先不去关心如何实现时间更新的,先看看咱们是如何进行依赖注入的;咱们在MyController
这个函数中设置的参数名称分别是$scope
和$timeout
因此在程序运行到这个函数的时候,AngularJS
会在内部调用函数对象的toString()
方法,假定参数的名称就是依赖的名称,分析并提取出函数的参数列表,而后经过$injector
将这些参数注入进对象的实例。
须要注意的地方:
AngularJS
的版本低于1.3.0时才能够成功运行。AngularJS
须要原始未经压缩的参数列表来进行解析。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"];
对上面代码的解释:
咱们给咱们的函数设置的参数名称分别是s
和t
,而后咱们在后面使用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
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(); }]);
须要注意的地方,行内声明的方式容许咱们直接传入一个参数数组,而不是一个函数。数组的元素是字符串,它们表明的是能够被注入到对象中的依赖名字,最后一个参数就是依赖注入的目标函数对象自己。
到这里已经把AngularJS
的依赖注入方法说得差很少了,不过还有一点,就是咱们上面的方法都依赖一个服务,那就是$injector
,我后面会和你们一块儿来探讨一下这个东西究竟是什么东西。
还有若是你以为我上面所说的有些地方是不对的,还望指出来,咱们一块儿进步^_^