本文参考AngularJs权威指南
依赖注入是一种设计模式,它可以去除对依赖关系的硬编码,从而可以在运行时改变甚至移除依赖关系。
从功能上看,依赖注入会事先自动查找依赖关系,并将注入目标告知被依赖的资源,这样就可以在目标需要时立即将资源注入进去。
AngularJS使用$injetor(注入器服务)来管理依赖关系的查询和实例化。
事实上, $injetor负责实例化AngularJS中所有的组件,包括应用的模块、指令和控制器等。
在运行时, 任何模块启动时$injetor都会负责实例化,并将其需要的所有依赖传递进去。
如果没有明确的声明, AngularJS会假定参数名称就是依赖的名称。
请注意,这个过程只适用于未经过压缩和混淆的代码,因为AngularJS需要原始未经压缩的参数列表来进行解析。
例子:(声明了一个模块和一个控制器)
angular.module('myApp', [])
.factory('greeter', function() {
return {
greet: function(msg) {alert(msg);}
}
})
.controller('MyController',function($scope, greeter) {
//其中function中的greeter就是依赖注入
$scope.sayHello = function() {
greeter.greet("Hello!");
};
});
<div ng-app="myApp">
<div ng-controller="MyController">
<button ng-click="sayHello()">Hellobutton>
div>
div>
当AngularJS实例化这个模块时,会查找greeter并自然而然地把对它的引用传递进去
上面例子效果如下:
AngularJS提供了显式的方法来明确定义一个函数在被调用时需要用到的依赖关系。
通过这种方法声明依赖,即使在源代码被压缩、参数名称发生改变的情况下依然能够正常工作。
var app=angular.module('myApp', [])
.factory('greeter', function() {
return {
greet: function(msg) {alert(msg);}
}
});
function MyController(renamed$scope, renamedGreeter) {
renamed$scope.sayHello = function() {
renamedGreeter.greet("Hello!");
}};
MyController.$inject = ['$scope', 'greeter'];
app.controller('MyController', MyController);
//注意这个语句,我这个例子弄了半天,各种报错,就是因为这个语句少了
我们给我们的函数设置的参数名称分别是renamed$scope和renamedGreeter,然后我们在后面使用
MyController.$inject=['$scope','greeter'];
显式的将我们需要的依赖注入到MyController函数中;
所以在MyController函数中,renamedscope代表scope,MyController.inject=[′scope’, ‘greeter’];代表greeter
AngularJS提供的注入声明的最后一种方式,是可以随时使用的行内注入声明。
允许我们在函数定义时从行内将参数传入。此外,它可以避免在定义过程中使用临时变量。
这种方式其实是一个语法糖,它同前面提到的通过$inject属性进行注入声明的原理是完全一样的
例子:(跟上面的例子一样,只是修改了js的部分)
angular.module('myApp', [])
.factory('greeter', function() {
return {
greet: function(msg) {alert(msg);}
}
})
.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
//这里注入的方式不一样了
//在定义一个AngularJS的对象时,行内声明的方式允许我们直接传入一个参数数组而不是一个函数。
//数组的元素是字符串,它们代表的是可以被注入到对象中的依赖的名字,最后一个参数就是依赖注入的目标函数对象本身。
$scope.sayHello = function() {
greeter.greet("Hello!");
};
}]);
演示效果还是一样的,就不贴图了
由于需要处理的是一个字符串组成的列表,行内注入声明也可以在压缩后的代码中正常运行。