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 相关文章推荐
select多选 multiple的使用示例
Jun 16 Javascript
Javascript 拖拽雏形(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
Javascript中实现trim()函数的两种方法
Feb 04 Javascript
关于网页中的无缝滚动的js代码
Jun 09 Javascript
Vue 源码分析之 Observer实现过程
Mar 29 Javascript
Vue.js 实现数据展示全部和收起功能
Sep 05 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
Apr 30 Javascript
微信小程序云开发 搭建一个管理小程序
May 17 Javascript
基于ssm框架实现layui分页效果
Jul 27 Javascript
js实现烟花特效
Mar 02 Javascript
vue-router 路由传参用法实例分析
Mar 06 Javascript
vue 子组件watch监听不到prop的解决
Aug 09 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使用ICQ网关发送手机短信
2013/10/30 PHP
ThinkPHP实现支付宝接口功能实例
2014/12/02 PHP
php curl 上传文件代码实例
2015/04/27 PHP
php mongodb操作类 带几个简单的例子
2016/08/25 PHP
判断客户端浏览器是否安装了Flash插件的多种方法
2010/08/11 Javascript
JavaScript对象之间的转换 jQuery对象和原声DOM
2011/03/07 Javascript
javascript基于HTML5 canvas制作画箭头组件
2014/06/25 Javascript
AngularJs Dependency Injection(DI,依赖注入)
2016/09/02 Javascript
vue.js内部自定义指令与全局自定义指令的实现详解(利用directive)
2017/07/11 Javascript
jQuery实现节点的追加、替换、删除、复制功能示例
2017/07/11 jQuery
快速掌握jquery分页插件jqPaginator的使用方法
2017/08/09 jQuery
Webpack实战加载SVG的方法
2017/12/26 Javascript
Auto.js自动收取自己和好友蚂蚁森林能量脚本
2018/06/28 Javascript
css配合JavaScript实现tab标签切换效果
2018/10/11 Javascript
利用Dectorator分模块存储Vuex状态的实现
2019/02/05 Javascript
jQuery实现的卷帘门滑入滑出效果【案例】
2019/02/18 jQuery
vue2配置scss的方法步骤
2019/06/06 Javascript
jquery 遍历hash操作示例【基于ajax交互】
2019/10/12 jQuery
微信小程序文章详情功能完整实例
2020/06/03 Javascript
解决vue axios跨域 Request Method: OPTIONS问题(预检请求)
2020/08/14 Javascript
[03:43]2014DOTA2西雅图国际邀请赛 newbee战队巡礼
2014/07/07 DOTA
python logging日志模块以及多进程日志详解
2018/04/18 Python
使用python的pandas为你的股票绘制趋势图
2019/06/26 Python
浅析Python 抽象工厂模式的优缺点
2020/07/13 Python
通过代码简单了解django model序列化作用
2020/11/12 Python
用OpenCV进行年龄和性别检测的实现示例
2021/01/29 Python
详解html5 shiv.js和respond.min.js
2018/01/24 HTML / CSS
英国花园家具中心:Garden Furniture Centre
2017/08/24 全球购物
Tiqets荷兰:出售欧洲最美丽的景点和博物馆门票
2018/01/09 全球购物
新闻专业推荐信范文
2013/11/20 职场文书
大学社团计划书
2014/05/01 职场文书
三八妇女节超市活动方案
2014/08/18 职场文书
Python pandas求方差和标准差的方法实例
2021/08/04 Python
React Fragment介绍与使用详解
2021/11/11 Javascript
MySQL数据库之内置函数和自定义函数 function
2022/06/16 MySQL
Springboot集成kafka高级应用实战分享
2022/08/14 Java/Android