1.背景介绍
依赖注入,我们打个比喻,以前原始社会,我们需要斧子,然后由于还没有社会分工,只能自己打磨一把来使用,对应在程序上是我们需要一个功能的时候只能自己创建,然后使用new等关键字来调用方法。
然后工业社会阶段,我们需要使用斧子的时候,只需要找到工厂,购买斧子就可以使用,共产主义社会,需要斧子的时候甚至不需要购买,直接坐等社会提供。
依赖注入的意思就是我们需要的东西不是我们自己创建的,而是第三方提供的,我们只需要引用就可以使用了。不需要的时候就不引用它。
依赖注入产生的背景:
传统应用程序通常是在类内部执行代码中主动创建这个类所依赖的其它对象,从而导致类与类之间发生紧密耦合,使得类难于测试和隔离,最终导致系统的扩展和维护异常困难。
解决方案:依赖注入用来解决组件之间依赖关系、配置及生命周期管理,通过转移对象控制权,可以解决类之间的耦合问题,对象与对象之间是松散耦合关系,更重要的是使得应用程序体系结构变得非常灵活,很好的体现了面向对象的设计法则之一----依赖设计原则。
2.知识剖析
一、依赖注入的原理:
程序运行过程中,如需另一个对象协作(调用它的方法、访问他的属性)时,无须在代码中创建被调用者,而是依赖于外部容器的注入,调用者仅通过声明某个组件就可以获得组件的控制权,而对该组件的依赖关系管理、查找、加载由外部完成。
二、依赖注入有什么用:
作用一:可以使我们能够轻松对组件进行测试
作用二:降低代码的逻辑复杂度
angular提供了几种很好的依赖注入机制,以下5个核心组件用来作为依赖注入value、factory、service、provider、constant
Value是一个简单的javascript对象,用于向控制器传递值(配置阶段)
工厂(factory)是用于返回函数的值。它根据需求创造值,每当一个服务或控制器需要。它通常使用一个工厂函数来计算并返回对应值
AngularJS中通过provider创建一个service、factory等(配置阶段)。Provider中提供了一个factory方法get(),它用于返回value/service/factory。
服务是一个单一的JavaScript包含了一组函数对象来执行某些任务。服务使用service()函数,然后注入到控制器的定义。
constant(常量)用来在配置阶段传递数值,注意这个常量在配置阶段是不可用的。
当我们想要创建一个服务,并且这个服务只需要返回数据时,就可以使用constant(name,value)和value(name,value),不过,它们有两个显著的区别:
1.value不可以在config里注入,但是constant可以。
2.value可以修改,但是constant不可以修改,一般直接用constant配置一些需要经常使用的数据。
通常情况下,可以通过value()来注册服务对象或函数,用constant()来配置数据。
3.常见问题
一、依赖注入的几种方法如何使用。
4.解决方案
依赖注解有三种方式,(数组标注、添加$inject属性、隐式声明)。
其中前两种在代码minify时不会被破坏,推荐使用第一种方式。
第三种方式,书写最为简单明了,但是不能对它直接进行minify,需要改写为前两种。
一、数组标注
js压缩混淆不会有影响,优先考虑用该方式为组件定义依赖。在代码中通过在第二个数组类型的参数中声明了'$scope','greeter'等依赖,数组最后一个元素为实际的构造方法,注意在构造方法的参数列表与其面的数组元素是一一对应的。
someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
// ...
}]);
二、显式注入声明($inject属性)
AngularJS提供了显式的方法来明确定义一个函数在被调用时需要用到的依赖关系。通过这种方法声明依赖,即使在源代码被压缩、参数名称发生改变的情况下依然能够正常工作。我们给我们的函数设置的参数名称分别是$scope和greeter,然后我们在后面使用MyController.$inject=['$scope','greeter'];显式的将我们需要的依赖注入到MyController函数中;
var MyController = function($scope, greeter) {
// ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);
三、隐式声明依赖
最简单的声明依赖的方式就是让设构造方法的参数与依赖的名字一样。如果没有明确的声明,AngularJS会假定参数名称就是依赖的名称。请注意,这个过程只适用于未经过压缩和混淆的代码,因为AngularJS需要原始未经压缩的参数列表来进行解析当AngularJS实例化这个模块时,会查找greeter并自然而然地把对它的引用传递进去这里我们先看一个简单的依赖注入的例子。
someModule.controller('MyController', function($scope, greeter) {
// ...
});
5.编码实战
6.扩展思考
这些依赖组件的本质是什么?
factory,service以及value全部都是用来定义一个provider的简写,它们提供了一种方式来定义一个provider而无需输入所有的复杂的代码。
7.参考文献
参考一:详解依赖注入http://www.yiibai.com/angularjs/angularjs_dependency_injection.html
参考二:理解依赖注入http://sentsin.com/web/663.html
参考三:AngularJS中的依赖注入实际应用场景?https://www.zhihu.com/question/28097646
参考四:AngularJS基础之依赖注入的几种方法http://blog.csdn.net/luo_xinran/article/details/52153830
8.更多讨论
AngularJS中的依赖注入与不用依赖注入的其他框架相比,有何优点?
一、模板功能强大丰富,并且是声明式的,自带了丰富的Angular指令;
二、是一个比较完善的前端MVC框架,包含模板,数据双向绑定,路由,模块化,服务,过滤器,依赖注入等所有功能;
三、依赖注入简化了组件之间处理依赖的过程(即解决依赖)。没有依赖注入,就不得不以某种方式自己查找$scope,很可能得使用全局变量。这虽然能够工作,但是不如AngularJS的依赖注入技术这么简单。
四、在开发中使用依赖注入的主要好处是AngularJS负责管理组件并在需要的时候提供给相应函数。依赖注入还能够为测试带来好处,因为它允许你使用假的或者模拟的对象来代替真实的组件,从而让开发者专注于程序的特定部分。
PPT地址:https://ptteng.github.io/PPT/PPT/js-07-What-is-dependency-injection-in-angularJS.html#/
视频地址:https://v.qq.com/x/page/f0507met1qo.html
今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~
下期预告:angular路由,不见不散~
------------------------------------------------------------------------------------------------------------------------
技能树.IT修真院
“我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,掌控自己学习的节奏,学习的路上不再迷茫”。
这里是技能树.IT修真院,成千上万的师兄在这里找到了自己的学习路线,学习透明化,成长可见化,师兄1对1免费指导。快来与我一起学习吧~
我的邀请码:96194340,或者你可以直接点击此链接:http://www.jnshu.com/login/1/96194340