1.背景介绍
今天给大家讲的是angular的依赖注入,首先,我们要介绍一下什么是依赖注入
依赖注入,我们打个比喻,以前原始社会,我们需要斧子,然后由于还没有社会分工,只能自己打磨一把来使用,对应在程序上是我们需要一个功能的时候只能自己创建,然后使用new等关键字来调用方法。
然后工业社会阶段,我们需要使用斧子的时候,只需要找到工厂,购买斧子就可以使用,共产主义社会,需要斧子的时候甚至不需要购买,直接坐等社会提供。
依赖注入的意思就是我们需要的东西不是我们自己创建的,而是第三方提供的,我们只需要引用就可以使用了。
不需要的时候就不引用它。
依赖注入的优点:不用自己去管理众多对象,代码耦合性低,方便开发;便于维护,便于模块化测试。
2.知识剖析
依赖注入的原理:程序运行过程中,如需另一个对象协作(调用它的方法、访问他的属性)时,无须在代码中创建被调用者,而是依赖于外部容器的注入, 调用者仅通过声明某个组件就可以获得组件的控制权,而对该组件的依赖关系管理、查找、加载由外部完成。
angular提供了几种很好的依赖注入机制,以下5个核心组件用来作为依赖注入
value、factory、service、provider、constant、
值工厂 服务提供者 常值
值是简单的JavaScript对象,它是用来将值传递过程中的配置相位控制器。
var mainApp = angular.module("mainApp", []);
//create a value object as "defaultInput" and pass it a data.
mainApp.value("defaultInput", 5);
mainApp.controller('CalcController', function($scope, CalcService, defaultInput) {
$scope.number = defaultInput;
$scope.result = CalcService.square($scope.number);
$scope.square = function() {
$scope.result = CalcService.square($scope.number);
}
});
工厂是用于返回函数的值。它根据需求创造值,每当一个服务或控制器需要。它通常使用一个工厂函数来计算并返回对应值
var mainApp = angular.module("mainApp", []);
mainApp.factory('MathService', function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b
}
return factory;
});
mainApp.service('CalcService', function(MathService){
this.square = function(a) {
return MathService.multiply(a,a);
}
});
提供者所使用的AngularJS内部创建过程中配置阶段的服务,工厂等(相AngularJS引导自身期间)。下面提到的脚本,可以用来创建,我们已经在前面创建MathService。提供者是一个特殊的工厂方法以及get()方法,用来返回值/服务/工厂。
var mainApp = angular.module("mainApp", []);
mainApp.config(function($provide) {
$provide.provider('MathService', function() {
this.$get = function() {
var factory = {};
factory.multiply = function(a, b) {
return a * b;
}
return factory;
};
});
});
服务是一个单一的JavaScript包含了一组函数对象来执行某些任务。服务使用service()函数,然后注入到控制器的定义。
var mainApp = angular.module("mainApp", []);
mainApp.service('CalcService', function(MathService){
this.square = function(a) {
return MathService.multiply(a,a);
}
});
mainApp.controller('CalcController', function($scope, CalcService, defaultInput) {
$scope.number = defaultInput;
$scope.result = CalcService.square($scope.number);
$scope.square = function() {
$scope.result = CalcService.square($scope.number);
}
});
3.常见问题
a、依赖注入的几种方法如何使用
b、angular依赖注入的时候,controller里面注入的参数和function的参数列表顺序问题。
4.解决方案
a 依赖注入有三种方式进行注入:推断式注入声明,显式注入声明,行内注入声明:
推断式注入声明
如果没有明确的声明, AngularJS会假定参数名称就是依赖的名称。请注意,这个过程只适用于未经过压缩和混淆的代码,因为AngularJS需要原始未经压缩的参数列表来进行解析。当AngularJS实例化这个模块时,会查找greeter并自然而然地把对它的引用传递进去.
显式注入声明
AngularJS提供了显式的方法来明确定义一个函数在被调用时需要用到的依赖关系。通过这种方法声明依赖,即使在源代码被压缩、参数名称发生改变的情况下依然能够正常工作。我们给我们的函数设置的参数名称分别是renamed$scope和renamedGreeter,然后我们在后面使用
MyController.$inject=['$scope','greeter'];
显式的将我们需要的依赖注入到MyController函数中;
所以在MyController函数中,renamedscope代表scope,MyController.inject=[′scope’, ‘greeter’];代表greeter
行内注入声明
AngularJS提供的注入声明的最后一种方式,是可以随时使用的行内注入声明。允许我们在函数定义时从行内将参数传入。此外,它可以避免在定义过程中使用临时变量。它同前面提到的通过$inject属性进行注入声明的原理是完全一样的
b:这里需要注意的是,行内注入声明的时候controller和function里面的参数列表的顺序是一一对应的,否则就会注入失败,导致程序不执行或者执行失败。并且没有报错信息。所以在一开始就需要注意这里。
5.编码实战
6.扩展思考
Q:这些依赖组件的本质是啥?
A:factory,service以及value全部都是用来定义一个provider的简写, 它们提供了一种方式来定义一个provider而无需输入所有的复杂的代码。
7.参考文献
参考:详解依赖注入 参考:理解依赖注入 参考:深究依赖注入
8.更多讨论
AngularJS中的依赖注入组件的应用场景?