AngularJS的依赖注入实例分析(使用module和injector)


Posted in Javascript onJanuary 19, 2017

本文实例分析了AngularJS的依赖注入。分享给大家供大家参考,具体如下:

依赖注入(DI)的好处不再赘言,使用过spring框架的都知道。AngularJS作为前台js框架,也提供了对DI的支持,这是JavaScript/jQuery不具备的特性。angularjs中与DI相关有angular.module()、angular.injector()、 $injector、$provide。对于一个DI容器来说,必须具备3个要素:服务的注册、依赖关系的声明、对象的获取。比如spring中,服务的注册是通过xml配置文件的<bean>标签或是注解@Repository、@Service、@Controller、@Component实现的;对象的获取可以ApplicationContext.getBean()实现;依赖关系的声明,即可以在xml文件中配置,也可以使用@Resource等注解在Java代码中声明。在angular中,module和$provide相当于是服务的注册;injector用来获取对象(angular会自动完成依赖的注入);依赖关系的声明在angular中有3种方式。下面从这3个方面,介绍下angular的DI。

1、angular.module()创建、获取、注册angular中的模块

The angular.module() is a global place for creating, registering and retrieving Angular modules.When passed two or more arguments, a new module is created. If passed only one argument, an existing module (the name passed as the first argument to module) is retrieved。

// 传递参数不止一个,代表新建模块;空数组代表该模块不依赖其他模块
var createModule = angular.module("myModule", []);
// 只有一个参数(模块名),代表获取模块
// 如果模块不存在,angular框架会抛异常
var getModule = angular.module("myModule");
// true,都是同一个模块
alert(createModule == getModule);

该函数既可以创建新的模块,也可以获取已有模块,是创建还是获取,通过参数的个数来区分。

angular.module(name, [requires], [configFn]);
name:字符串类型,代表模块的名称;
requires:字符串的数组,代表该模块依赖的其他模块列表,如果不依赖其他模块,用空数组即可;
configFn:用来对该模块进行一些配置。

现在我们知道如何创建、获取模块了,那么模块究竟是什么呢?官方的Developer Guide上只有一句话:You can think of a module as a Container for the different parts of your app ? controllers, services, filters, directives, etc.现在我还不太理解,大致就是说模块是一些功能的集合,如控制器、服务、过滤器、指令等子元素组成的整体。现在解释不了,先遗留。

2、$provide和模块的关系

The $provide service has a number of methods for registering components with the $injector. Many of these functions are also exposed on angular.Module.

之前提到过:module和provide是用来注册服务到injector中的。查看官方的API,可以看到$provide提供了provide()、constant()、value()、factory()、service()来创建各种不同性质的服务;angular.Module中也提供了这5个服务注册方法。其实2者功能是完全一样的,就是用来向DI容器注册服务到injector中。

官方API下的auto有$provide 和 $injector,Implicit module which gets automatically added to each $injector.按照字面意思是说,每一个injector都有这2个隐含的服务。但1.2.25版本中,感觉没有办法获取injector中的$provide。不知道这是为什么?一般来说也不需要显示使用这个服务,直接使用module中提供的API即可。

var injector = angular.injector();
alert(injector.has("$provide"));//false
alert(injector.has("$injector"));//true

3、angular.injector()

使用angular.injector();也能获取到注入器,但是没有和模块绑定。这种做法是没有意义的,相当于是你创建了一个空的DI容器,里面都没有服务别人怎么用呢。正确的做法是,在创建注入器的时候,指定需要加载的模块。

// 创建myModule模块、注册服务
var myModule = angular.module('myModule', []);
myModule.service('myService', function() {
      this.my = 0;
});
// 创建herModule模块、注册服务
var herModule = angular.module('herModule', []);
herModule.service('herService', function() {
      this.her = 1;
});
// 加载了2个模块中的服务
var injector = angular.injector(["myModule","herModule"]);
alert(injector.get("myService").my);
alert(injector.get("herService").her);

如果加载了多个模块,那么通过返回的injector可以获取到多个模块下的服务。这个例子中如果只加载了myMoudle,那么得到的injector就不能访问herMoudle下的服务。这里特别需要注意下:angular.injector()可以调用多次,每次都返回新建的injector对象。

var injector1 = angular.injector(["myModule","herModule"]);
var injector2 = angular.injector(["myModule","herModule"]);
alert(injector1 == injector2);//false

4、angular中三种声明依赖的方式

angular提供了3种获取依赖的方式:inference、annotation、inline方式。

// 创建myModule模块、注册服务
var myModule = angular.module('myModule', []);
myModule.service('myService', function() {
      this.my = 0;
});
// 获取injector
var injector = angular.injector(["myModule"]);
// 第一种inference
injector.invoke(function(myService){alert(myService.my);});
// 第二种annotation
function explicit(serviceA) {alert(serviceA.my);};
explicit.$inject = ['myService'];
injector.invoke(explicit);
// 第三种inline
injector.invoke(['myService', function(serviceA){alert(serviceA.my);}]);

其中annotation和inline方式,对于函数参数名称没有要求,是推荐的做法;inference方式强制要求参数名称和服务名称一致,如果JS代码经过压缩或者混淆,那么功能会出问题,不建议使用这种方式。

希望本文所述对大家AngularJS程序设计有所帮助。

Javascript 相关文章推荐
向左滚动文字 js代码效果
Aug 17 Javascript
js实现鼠标触发图片抖动效果的方法
Feb 27 Javascript
HTML Table 空白单元格补全的简单实现
Oct 13 Javascript
JS实现动画兼容性的transition和transform实例分析
Dec 13 Javascript
Angular2库初探
Mar 01 Javascript
JavaScript基础之静态方法和实例方法分析
Dec 26 Javascript
Vue 实现前端权限控制的示例代码
Jul 09 Javascript
小程序识别身份证,银行卡,营业执照,驾照的实现
Nov 05 Javascript
使用JS监听键盘按下事件(keydown event)
Nov 07 Javascript
JS原型和原型链原理与用法实例详解
Feb 05 Javascript
微信小程序实现简单文字跑马灯
May 26 Javascript
vue+element ui实现锚点定位
Jun 29 Vue.js
学好js,这些js函数概念一定要知道【推荐】
Jan 19 #Javascript
AngularJS 使用ng-repeat报错 [ngRepeat:dupes]
Jan 19 #Javascript
Reactjs实现通用分页组件的实例代码
Jan 19 #Javascript
react.js 翻页插件实例代码
Jan 19 #Javascript
JavaScript自动点击链接 防止绕过浏览器访问的方法
Jan 19 #Javascript
AngularJS使用angular.bootstrap完成模块手动加载的方法分析
Jan 19 #Javascript
创建一般js对象的几种方式
Jan 19 #Javascript
You might like
调整优化您的LAMP应用程序的5种简单方法
2011/06/26 PHP
PHP5 的对象赋值机制介绍
2011/08/02 PHP
解析zend studio中直接导入svn中的项目的方法步骤
2013/06/21 PHP
PHP数据库链接类(PDO+Access)实例分享
2013/12/05 PHP
ThinkPHP自动转义存储富文本编辑器内容导致读取出错的解决方法
2014/08/08 PHP
浅谈PHP正则中的捕获组与非捕获组
2016/07/18 PHP
php微信公众号开发之翻页查询
2018/10/20 PHP
php写入txt乱码的解决方法
2019/09/17 PHP
Javascript实例教程(19) 使用HoTMetal(5)
2006/12/23 Javascript
使用jquery.upload.js实现异步上传示例代码
2014/07/29 Javascript
微信小程序组件 contact-button(客服会话按钮)详解及实例代码
2017/01/10 Javascript
bootstrap警告框示例代码分享
2017/05/17 Javascript
Angular.js中window.onload(),$(document).ready()的写法浅析
2017/09/28 Javascript
jQuery实现获取table中鼠标click点击位置行号与列号的方法
2017/10/09 jQuery
JavaScript轮播停留效果的实现思路
2018/05/24 Javascript
JQuery模拟实现网页中自定义鼠标右键菜单功能
2018/11/14 jQuery
详解Vue-cli3 项目在安卓低版本系统和IE上白屏问题解决
2019/04/14 Javascript
CountUp.js实现数字滚动增值效果
2019/10/17 Javascript
[02:56]《DAC最前线》之国外战队抵达上海备战亚洲邀请赛
2015/01/28 DOTA
python通过自定义isnumber函数判断字符串是否为数字的方法
2015/04/23 Python
Python中的localtime()方法使用详解
2015/05/22 Python
itchat和matplotlib的结合使用爬取微信信息的实例
2017/08/25 Python
python利用正则表达式搜索单词示例代码
2017/09/24 Python
python 读取修改pcap包的例子
2019/07/23 Python
基于Pytorch SSD模型分析
2020/02/18 Python
解决Django Haystack全文检索为空的问题
2020/05/19 Python
Python+unittest+DDT实现数据驱动测试
2020/11/30 Python
Html5页面二次分享的实现
2018/07/30 HTML / CSS
猫途鹰英国网站:TripAdvisor英国(旅游社区和旅游评论)
2016/08/30 全球购物
世界最大的海报和艺术印刷商店:AllPosters.com
2017/02/01 全球购物
彪马英国官网:PUMA英国
2019/02/11 全球购物
编写一个类体现构造,公有,私有方法,静态,私有变量
2013/08/10 面试题
发展部经理职责规定
2014/02/22 职场文书
道路交通事故赔偿协议书
2014/10/24 职场文书
关于MySQL临时表为什么可以重名的问题
2022/03/22 MySQL
python语言中pandas字符串分割str.split()函数
2022/08/05 Python