这里是修真院前端小课堂,每篇分享文从
【背景介绍】【知识剖析】【常见问题】【解决方案】【编码实战】【扩展思考】【更多讨论】【参考文献】
八个方面深度解析前端知识/技能,本篇分享的是:
【AngularJS中的依赖注入是什么?】
大家好,我是IT修真院深圳分院第12期的学员韩鹏,一枚正直纯洁善良的前端程序员,今天给大家分享一下,修真院官网JS任务7,深度思考中的知识点——AngularJS中的依赖注入是什么?
1、背景介绍
在软件工程中,依赖注入是实现控制反转的一种软件设计模式,一个依赖是一个被其他对象(client)调用的对象(服务),注入则是将被依赖的对象(service)实例传递给依赖对象(client)的行为。将 被依赖的对象传给依赖者,而不需要依赖者自己去创建或查找所需对象是DI的基本原则。 依赖注入允许程序设计遵从依赖倒置原则(简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合) 调用者(client)只需知道服务的接口,具体服务的查找和创建由注入者(injector)负责处理并提供给client,这样就分离了服务和调用者的依赖,符合低耦合的程序设计原则。
优点:
松耦合,可重用
提高了组件的可测试性
2、知识剖析
在Angular中DI是无处不在的,你可以用它来定义一个组件,也可以提供module实现run和config代码块。
- 像services, directives, filters 和 animations这样的组件都由一个工厂方法或者构造函数定义,在此service和value组件可以作为依赖注入到这些组件当中。
- Controllers通过一个构造函数定义,一样service和value组件可以作为依赖注入到组件当中,但他们也有着特殊的依赖关系。
- Module的run方法接受一个函数,在函数的参数中作为依赖可以注入service,value和constant组件,但是不能注入providers。
- Module的config方法接受一个函数,在函数的参数中作为依赖可以注入provider和constant组件,但是不能注入service和value。
AngularJS提供了很好的依赖注入机制,以下5个核心组件用来作为依赖注入:value、factory、service、provider、constant。
value
Value 是一个简单的 javascript 对象,用于向控制器传递值(配置阶段):
angular.module(, []);
.value(, );
...
.controller(, (, , ) {
.number ;
.result .square(.number);
.square () {
.result .square(.number);
}
});
factory
factory 是一个函数用于返回值。在 service 和 controller 需要时创建。
通常我们使用 factory 函数来计算或返回值。
angular.module(, []);
.factory(, () {
factory {};
factory.multiply (, ) {
}
factory;
});
.service(, (){
.square () {
.multiply(,);
}
});
...
provider
AngularJS 中通过 provider 创建一个 service、factory等(配置阶段)。
Provider 中提供了一个 factory 方法 get(),它用于返回 value/service/factory。
angular.module(, []);
...
.config(() {
.provider(, () {
.$get () {
factory {};
factory.multiply (, ) {
;
}
factory;
};
});
});
constant
constant(常量)用来在配置阶段传递数值,注意这个常量在配置阶段是不可用的。
mainApp.constant("configParam", "constant value");
3、常见问题
AngularJS依赖注入的方法
4、解决方案
- 通过函数的参数进行推断式注入声明(隐式声明)
如果没有明确的声明, AngularJS会假定参数名称就是依赖的名称。因此,它会在内部调用函数对象的toString()方法,分析并提取出函数的参数列表,然后通过 $injector将这些参数注入进对象实例。
- 显式注入声明
AngularJS提供了显式的方法来明确定义一个函数在被调用时需要用到的依赖关系。
通过这种方法声明依赖,即使在源代码被压缩、参数名称发生改变的情况下依然能够正常工作。
需要注意的地方:
对于这种声明方式来讲,参数的顺序是十分重要的,因为$inject数组元素的顺序必须和注入的参数的顺序一一对应。
- 行内注入声明
AngularJS提供的行内注入方法实际上是一种语法糖,它与前面的提到的通过$inject属性进行声明的原理是一样的,但是允许我们在函数定义的时候从行内将参数传入,这种方法方便,简单,而且避免了在定义的过程中使用临时变量。
需要注意的地方:
行内声明的方式允许我们直接传入一个参数数组,而不是一个函数。数组的元素是字符串,它们代表的是可以被注入到对象中的依赖名字,最后一个参数就是依赖注入的目标函数对象本身。
5、编码实战
6、扩展思考
AngularJS依赖注入有什么优点?
一、模板功能强大丰富,并且是声明式的,自带了丰富的Angular指令;
二、是一个比较完善的前端MVC框架,包含模板,数据双向绑定,路由,模块化,服务,过滤器,依赖注入等所有功能;
三、依赖注入简化了组件之间处理依赖的过程(即解决依赖)。没有依赖注入,就不得不以某种方式自己查找$scope,很可能得使用全局变量。这虽然能够工作,但是不如AngularJS的依赖注入技术这么简单。
四、在开发中使用依赖注入的主要好处是AngularJS负责管理组件并在需要的时候提供给相应函数。依赖注入还能够为测试带来好处,因为它允许你使用假的或者模拟的对象来代替真实的组件,从而让开发者专注于程序的特定部分。
7、参考文献
参考一:Angular依赖注入详解————http://www.cnblogs.com/leonwa...
参考二:玩转 AngualrJS 的依赖注入————https://segmentfault.com/a/11...
参考三:理解AngularJS中的依赖注入————http://www.html-js.com/articl...
8、更多讨论
问:什么适合使用service方法?
答:service()方法很适合使用在功能控制比较多的service里面。
注意:需要使用.config()来配置service的时候不能使用service()方法
问:service和factory的区别
答:factory 是普通函数,可以返回任何东西。service 是构造函数,可以不返回东西。功能相同。
问:推荐使用行内注入声明的原因?
答:写法上比显式注入声明更简单明了,比隐式注入声明更可靠(由于Javascript可以被压缩,AngularJS又是通过解析服务名称找到对应Service的,因此Javascript压缩之后AngularJS将无法找到指定的Service,但字符串不会被压缩,因此单独以字符串指定Service的名称可以避免这个问题)。
今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~
更多内容,可以加入IT交流群565734203与大家一起讨论交流
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。