AngularJS学习第二篇 AngularJS依赖注入


Posted in Javascript onFebruary 13, 2017

简介:

首先我们需要理解什么是依赖注入?
控制反转和依赖注入有什么区别?

假定:应用程序A,需要访问外部资源C。这里使用了容器B(是指用来实现 IOC/DI 功能的一个框架程序)。
A需要访问C
B获取C然后返回给A
IOC inversion of control 控制反转:站在容器角度。B控制A,由B反向的向A注入C。即容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
DI Dependency Injection 依赖注入:站在应用程序的角度。A依赖B获取C,B将C注入A。即应用程序依赖容器创建并注入它所需要的外部资源。

AngularJS依赖注入

Provider服务($provide)

AngularJS 提供很好的依赖注入机制。以下5个核心组件用来作为依赖注入:

value
factory
service
provider
constant
decorator (打酱油)

Constant

定义常量用的,这货定义的值当然就不能被改变,它可以被注入到任何地方,但是不能被装饰器(decorator)装饰

var app = angular.module('app', []);
app.config(function ($provide) {
 $provide.constant('movieTitle', 'The Matrix');
});
app.controller('ctrl', function (movieTitle) {
 expect(movieTitle).toEqual('The Matrix');
});
// 语法糖:
app.constant('movieTitle', 'The Matrix');

Value

这货可以是string,number甚至function,它和constant的不同之处在于,它可以被修改,不能被注入到config中,但是它可以被decorator装饰

var app = angular.module('app', []);
app.config(function ($provide) {
 $provide.value('movieTitle', 'The Matrix')
});
app.controller('ctrl', function (movieTitle) {
 expect(movieTitle).toEqual('The Matrix');
});
// 语法糖:
app.value('movieTitle', 'The Matrix');

Service

它是一个可注入的构造器,在AngularJS中它是单例的,用它在Controller中通信或者共享数据都很合适。

var app = angular.module('app' ,[]);
app.config(function ($provide) {
 $provide.service('movie', function () {
  this.title = 'The Matrix';
 });
});
app.controller('ctrl', function (movie) {
 expect(movie.title).toEqual('The Matrix');
});
// 语法糖:
app.service('movie', function () {
 this.title = 'The Matrix';
});

Factory

它是一个可注入的function,它和service的区别就是:factory是普通function,而service是一个构造器(constructor),这样Angular在调用service时会用new关键字,而调用factory时只是调用普通的function,所以factory可以返回任何东西,而service可以不返回(可查阅new关键字的作用)。

var app = angular.module('app', []);
app.config(function ($provide) {
 $provide.factory('movie', function () {
  return {
   title: 'The Matrix';
  }
 });
}); 
app.controller('ctrl', function (movie) {
 expect(movie.title).toEqual('The Matrix');
});
// 语法糖
app.factory('movie', function () {
 return {
  title: 'The Matrix';
 }
});

Provider

provider是他们的老大,上面的几乎(除了constant)都是provider的封装,provider必须有一个$get方法,当然也可以说provider是一个可配置的factory。

var app = angular.module('app', []);
app.provider('movie', function () {
 var version;
 return {
  setVersion: function (value) {
   version = value;
  },
  $get: function () {
   return {
     title: 'The Matrix' + ' ' + version
   }
  }
 }
});
app.config(function (movieProvider) {
 movieProvider.setVersion('Reloaded');
});
app.controller('ctrl', function (movie) {
 expect(movie.title).toEqual('The Matrix Reloaded');
});

Decorator

这个比较特殊,它不是provider,它是用来装饰其他provider的,而前面也说过,他不能装饰Constant,因为实际上Constant不是通过provider()方法创建的。

var app = angular.module('app', []);
app.value('movieTitle', 'The Matrix');
app.config(function ($provide) {
 $provide.decorator('movieTitle', function ($delegate) {
  return $delegate + ' - starring Keanu Reeves';
 });
});
app.controller('myController', function (movieTitle) {
 expect(movieTitle).toEqual('The Matrix - starring Keanu Reeves');
});

总结:

所有的供应商都只被实例化一次,也就说他们都是单例的
除了constant,所有的供应商都可以被装饰器(decorator)装饰
value就是一个简单的可注入的值
service是一个可注入的构造器
factory是一个可注入的方法
decorator可以修改或封装其他的供应商,当然除了constant
provider是一个可配置的factory

上述来源:(AngularJS中的Provider们:Service和Factory等的区别)https://segmentfault.com/a/1190000003096933

注入器($injector)

注入器负责从我们通过 provide 创建的服务中创建注入的实例。只要你编写了一个带有可注入性的参数,你都能看到注入器是如何运行的。每一个 AngularJS 应用都有唯一一个 injector,当应用启动的时候它被创造出来,你可以通过将 injector 注入到任何可注入函数中来得到它($injector 知道如何注入它自己!)。
一旦你拥有了 injector,你可以动过调用 get 函数来获得任何一个已经被定义过的服务的实例。

var movie = $injector.get('movie');
expect(movie.title).toEqual('The Matrix Reloaded');

注入器同样也负责将服务注入到函数中;例如,你可以魔法般的将服务注入到任何函数中,只要你使用了注入器的 invoke 方法:

var myFunction = function(movie) {
 return movie.title;
};
$injector.invoke(myFunction);

如果注入器只是创建一个服务的实例一次的话,那么它也没什么了不起的。它的厉害之处在于,他能够通过服务名称缓存从一个 provider 中返回的任何东西,当你下一次再使用这个服务时,你将会得到同一个对象。
因此,你可以通过调用 injector.invike 将服务注入到任何函数中也是合情合理的了。包括:

  • 控制器定义函数
  • 指令定义函数
  • 过滤器定义函数
  • provider中的$get方法(也就是factory函数)

由于constant和value总是返回一个静态值,它们不会通过注入器被调用,因此你不能在其中注入任何东西。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
将CKfinder整合进CKEditor3.0的新方法
Jan 10 Javascript
使用JS或jQuery模拟鼠标点击a标签事件代码
Mar 10 Javascript
理解JS事件循环
Jan 07 Javascript
让浏览器崩溃的12行JS代码(DoS攻击分析及防御)
Oct 10 Javascript
bootstrap选项卡使用方法解析
Jan 11 Javascript
React创建组件的三种方式及其区别
Jan 12 Javascript
使用vue的v-for生成table并给table加上序号的实例代码
Oct 27 Javascript
AngularJS实现的鼠标拖动画矩形框示例【可兼容IE8】
May 17 Javascript
JS实现基本的网页计算器功能示例
Jan 16 Javascript
js 获取本周、上周、本月、上月、本季度、上季度的开始结束日期
Feb 01 Javascript
axios解决高并发的方法:axios.all()与axios.spread()的操作
Nov 09 Javascript
html5 录制mp3音频支持采样率和比特率设置
Jul 15 Javascript
关于不同页面之间实现参数传递的几种方式讨论
Feb 13 #Javascript
如何用js判断dom是否有存在某class的值
Feb 13 #Javascript
AngularJS学习第一篇 AngularJS基础知识
Feb 13 #Javascript
详解Javascript中DOM的范围
Feb 13 #Javascript
JS简单判断函数是否存在的方法
Feb 13 #Javascript
浅谈js中的变量名和函数名重名
Feb 13 #Javascript
学习使用jQuery表单验证插件和日历插件
Feb 13 #Javascript
You might like
令PHP初学者头疼十四条问题大总结
2008/11/12 PHP
《PHP编程最快明白》第二讲 数字、浮点、布尔型、字符串和数组
2010/11/01 PHP
php删除数组元素示例分享
2014/02/17 PHP
微信公众平台天气预报功能开发
2014/07/06 PHP
thinkphp在php7环境下提示Cannot use ‘String’ as class name as it is reserved的解决方法
2016/09/30 PHP
从新浪弄下来的全屏广告代码 与使用说明
2007/03/15 Javascript
js cookies 常见网页木马挂马代码 24小时只加载一次
2009/04/13 Javascript
火狐4、谷歌12不支持Jquery Validator的解决方法分享
2011/06/20 Javascript
js精度溢出解决方案
2012/12/02 Javascript
JS解决url传值出现中文乱码的另类办法
2013/04/08 Javascript
JavaScript实现将xml转换成html table表格的方法
2015/04/17 Javascript
基于jQuey实现鼠标滑过变色(整行变色)
2015/12/07 Javascript
JS深度拷贝Object Array实例分析
2016/03/31 Javascript
require.js 加载 vue组件 r.js 合并压缩的实例
2016/10/14 Javascript
Node.js复制文件的方法示例
2016/12/29 Javascript
js+html5实现半透明遮罩层弹框效果
2020/08/24 Javascript
C#实现将一个字符转换为整数
2017/12/12 Javascript
Vue自定义弹窗指令的实现代码
2018/08/13 Javascript
vue2.0父子组件间传递数据的方法
2018/08/16 Javascript
[01:02:47]EG vs Secret 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
Python程序语言快速上手教程
2012/07/18 Python
简单谈谈Python中的json与pickle
2017/07/19 Python
Python控制Firefox方法总结
2019/06/03 Python
Django自定义用户表+自定义admin后台中的字段实例
2019/11/18 Python
python生成任意频率正弦波方式
2020/02/25 Python
python3跳出一个循环的实例操作
2020/08/18 Python
给同学的道歉信
2014/01/16 职场文书
土地转让协议书
2014/04/15 职场文书
小学一年级评语大全
2014/04/22 职场文书
教师党员群众路线教育实践活动心得体会
2014/11/04 职场文书
旷课检讨书
2015/01/26 职场文书
永远是春天观后感
2015/06/12 职场文书
Python趣味挑战之教你用pygame画进度条
2021/05/31 Python
代码解析React中setState同步和异步问题
2021/06/03 Javascript
教你使用Jenkins集成Harbor自动发布镜像
2022/04/03 Servers
SQL SERVER中的流程控制语句
2022/05/25 SQL Server