理解AngularJS中的依赖注入
AngularJS中的依赖注入非常的有用,它同时也是我们能够轻松对组件进行测试的关键所在。在本文中我们将会解释AngularJS依赖注入系统是如何运行的。
AngularJS 提供很好的依赖注入机制。以下5个核心组件用来作为依赖注入:
service
provider
value
factory
constant
Provider服务($provide)
$provide服务负责告诉Angular如何创造一个新的可注入的东西:即服务(service)。服务会被叫做provider的东西来定义,你可以使用$provide来创建一个provider。你需要使用$provide中的provider方法来定义一个provider,同时你也可以通过要求改服务被注入到一个应用的config函数中来获得$provide服务。
app.config(function($provide) { $provide.provider('greeting', function() { this.$get = function() { return function(name) { alert("Hello, " + name); }; }; }); });
在上面的例子中我们为一个服务定义了一个叫做greeting的新provider;我么可以把一个叫做greeting的变量注入到任何可注入的函数中(例如控制器)然后Angular就会调用这个provider的$get函数来返回这个服务的一个实例。在上面的例子中,被注入的是一个函数,它接受一个叫做name的参数并且根据这个参数alert一条信息。我们可以像下面这样使用它:
app.controller('MainController', function($scope, greeting) { $scope.onClick = function() { greeting('Ford Prefect'); }; });
现在有趣的事情来了。factory,service以及value全部都是用来定义一个providr的简写,它们提供了一种方式来定义一个provider而无需输入所有的复杂的代码。例如,你可以用下面的代码定义一个和前面完全相同的provider:
app.config(function($provide) { $provide.factory('greeting', function() { return function(name) { alert("Hello, " + name); }; }); });
这非常的重要,在幕后,AngularJS实际上是在调用前面出现的代码(就是$provide.provider的版本)。从字面上来说,这两种方法基本上没有差别。value方法也一样 – 如果我们需要从$get函数(也就是我们的factory函数)返回的值永远相同的话,我们可以使用value方法来编写更少的代码。例如如果我们的greeting服务总是返回相同的函数,我们可以使用value来进行定义:
app.config(function($provide) { $provide.value('greeting', function(name) { alert("Hello, " + name); }); });
再一次申明,以上两种方式的效果完全一样 – 只不过是代码的量不同而已
app.config(function($provide){...})
由于定义一个新的provider是如此的常用,AngularJS在模块对象上直接暴露了provider方法,以此来减少代码的输入量:
var myMod = angular.module('myModule', []); myMod.provider("greeting", ...); myMod.factory("greeting", ...); myMod.value("greeting", ...);
上面的代码和前面app.config(...)
的写法完全相同。
除了上面提到的可以注入的东西之外,还有一个constant方法。基本上,它和value的用法一致。我们会在后面来讨论两者的不同点。
为了巩固前面的学习成果,下面所有的代码所做的都是同一件事情:
myMod.provider('greeting', function() { this.$get = function() { return function(name) { alert("Hello, " + name); }; }; }); myMod.factory('greeting', function() { return function(name) { alert("Hello, " + name); }; }); myMod.value('greeting', function(name) { alert("Hello, " + name); });
注入器($injector)
注入器负责从我们通过$provide创建的服务中创建注入的实例。只要你编写了一个带有可注入性的参数,你都能看到注入器是如何运行的。每一个AngularJS应用都有唯一一个$injector,当应用启动的时候它被创造出来,你可以通过将$injector注入到任何可注入函数中来得到它($injector知道如何注入它自己!)。
一旦你拥有了$injector,你可以动过调用get函数来获得任何一个已经被定义过的服务的实例。例如:
var greeting = $injector.get('greeting'); greeting('Ford Prefect');
注入器同样也负责将服务注入到函数中;例如,你可以魔法般的将服务注入到任何函数中,只要你使用了注入器的invoke方法:
var myFunction = function(greeting) { greeting('Ford Prefect'); }; $injector.invoke(myFunction);
如果注入器只是创建一个服务的实例一次的话,那么它也没什么了不起的。它的厉害之处在于,他能够通过服务名称缓存从一个provider中返回的任何东西,当你下一次再使用这个服务时,你将会得到同一个对象。
因此,你可以通过调用$injector.invike将服务注入到任何函数中也是合情合理的了。包括:
- 控制器定义函数
- 指令定义函数
- 过滤器定义函数
- provider中的$get方法(也就是factory函数)
由于constant和value总是返回一个静态值,它们不会通过注入器被调用,因此你不能在其中注入任何东西。
配置provider
你可能会感到困惑:既然factorry和value能够节省那么多的代码,为什么还有人要使用provider。答案是provider允许我们进行一些配置。在前面我们已经提到过当你通过provider(或者其他简写方法)创建一个服务时,你实际上创建了一个新的provider,它将定义你的服务如何被创建。我们没有提到的是,这些provider可以被注入到config函数中,你可以和它们进行一些交互。
首先,AngularJS分两个阶段运行你的应用 – config阶段和run阶段。config阶段是你设置任何的provider的阶段。它也是你设置任何的指令,控制器,过滤器以及其它东西的阶段。在run阶段,AngularJS会编译你的DOM并启动你的应用。
你可以在myMod.config和myMod.run中添加任何代码 – 这两个函数分别在两个阶段运行。正如我们看到的,这些函数都是可以被注入的 – 我们在第一个例子中注入了内建的$provide函数。然而,值得注意的是在config阶段,只有provider能被注入(只有两个例外是$provide和$injector)。
例如,下面的代码就是错误的写法:
myMod.config(function(greeting) { //不会运行 -- greeting是一个服务的实例 //只有服务的provider能被注入到config中 });
但是你可以通过下面的方法注入provider:
myMod.config(function(greetingProvider) { // 这下好了! });
有一个例外:constant,由于它们不能被改变,因此它不能被注入到config中(这就是它和value之间的不同之处)。它们只能通过名字被获取。
无论何时你为一个服务定义了一个provider,这个provider的名字都是serviceProvider。在这里service是服务的名字。现在我们可以使用provider的力量来做一些更复杂的事情了!
myMod.provider('greeting', function() { var text = 'Hello, '; this.setText = function(value) { text = value; }; this.$get = function() { return function(name) { alert(text + name); }; }; }); myMod.config(function(greetingProvider) { greetingProvider.setText("Howdy there, "); }); myMod.run(function(greeting) { greeting('Ford Prefect'); });
现在我们在provider中拥有了一个叫做setText的函数,我们可以使用它来自定义我们alert的内容;我们可以再config中访问这个provider,调用setText方法并自定义我们的service。当我们最终运行我们的应用时,我们可以获取greeting服务,然后你会看到我们自定义的行为起作用了。
相关推荐
- **依赖注入**:Angular.js的DI系统允许开发者轻松地在组件之间共享服务,降低了代码的耦合度。 - **指令**:自定义HTML标签和属性,扩展了HTML的功能,使页面元素具备更多的交互性和动态性。 - **过滤器**:...
在前端开发领域,AngularJS(通常简称为Angular.js)是一个非常流行且强大的JavaScript框架,由Google维护。这个框架主要用于构建动态、单页Web应用程序(SPA),它提供了丰富的功能来简化前端开发过程,包括数据...
- **依赖注入(Dependency Injection,DI)**:Angular.js提供了一个强大的DI系统,使得组件之间能够轻松地共享服务和资源,无需手动实例化对象或管理依赖关系。 - **指令(Directives)**:Angular.js的一大创新是...
2. **依赖注入**:AngularJS的依赖注入系统允许开发者在不关心对象如何创建或管理的情况下,轻松地在组件间共享服务。只需声明所需的依赖,AngularJS就会自动注入。 3. **指令**:AngularJS中的指令扩展了HTML的...
2. **依赖注入**:Angular.js的依赖注入系统简化了代码结构,通过自动管理对象之间的依赖关系,使代码更易于测试和维护。 3. **指令系统**:Angular.js通过自定义HTML指令扩展了DOM,允许创建行为丰富的用户界面,...
3. 依赖注入:Angular.js支持依赖注入,这有利于模块化代码和组件的复用。 4. 指令(Directives):指令是Angular.js中非常核心的概念,允许你通过HTML标签、属性、类和注释来扩展HTML的语法。 5. 服务和工厂:用于...
Angular.js,作为一个强大的前端JavaScript框架,由Google维护,被广泛应用于构建复杂的单页应用(SPA)和后台管理系统。本篇将深入探讨Angular.js的核心特性、架构设计以及如何在实际项目中构建一个后台管理系统。 ...
AngularJS,作为一款由Google维护的前端JavaScript框架,是MVVM(Model-View-ViewModel)模式的杰出代表,以其强大的数据绑定、依赖注入和模块化功能深受开发者喜爱。在1.6.9这个版本中,我们看到对稳定性和性能的一...
1. **依赖注入**:AngularJS的依赖注入系统是其核心功能之一。在1.3版本中,依赖注入更加智能,能够自动识别并注入所需的依赖服务,使得代码更简洁,可维护性更强。 2. **$http服务增强**:在1.3版本中,$http服务...
Spring提供了一个全面的应用开发框架,包括依赖注入、事务管理、AOP(面向切面编程)等。Spring MVC是Spring框架的一部分,用于构建Web应用的模型-视图-控制器结构。MyBatis则是一个轻量级的持久层框架,它简化了...
3. **依赖注入(Dependency Injection)**:Angular.js的DI系统允许开发者轻松获取并管理应用程序中的服务,如 `$http` 用于HTTP请求,`$scope` 作为控制器与视图间的通讯桥梁。 4. **模块(Modules)**:Angular...
`ngModule`提供了一种创建和依赖注入模块的方法,这有助于保持代码的清晰性和可维护性。你可以通过`.module()`方法创建一个模块,并通过`.requires`参数指定其依赖的其他模块。 2. **组件化**: 1.5版本引入了组件...
Angular.js,通常简称为Angular,是由Google维护的一个开源JavaScript框架,用于构建单页应用程序(SPA)。这个框架的主要目标是简化前端开发,通过提供强大的数据绑定和依赖注入机制,让开发者可以更加专注于应用...
2. **依赖注入**:Angular.js使用依赖注入(DI)来管理组件之间的依赖关系。开发者无需手动实例化对象或管理对象间的依赖,而是由框架自动处理,提高了代码的可测试性和可维护性。 3. **指令系统**:Angular.js的指令...
1. **依赖注入**:AngularJS的核心特性之一是依赖注入(Dependency Injection,DI),它简化了代码的编写和测试。在1.3.0版本中,DI系统更加健壮,能够自动处理未定义的依赖,提高了代码的容错性。 2. **$scope**:...
AngularJs(简称ng)是一个用于...为了实现这些,ng引入了一些非常棒的特性,包括模板机制、数据绑定、模块、指令、依赖注入、路由。通过数据与模板的绑定,能够让我们摆脱繁琐的DOM操作,而将注意力集中在业务逻辑上。
Service是Angular.js中的一个核心概念,它是一种单例对象,可以在应用的任何地方被注入并使用。为了在Controllers之间传递参数,我们可以创建一个自定义Service,提供getter和setter方法来存储和获取数据。 ```...
Angular-apollo-angular.zip,为Angular和每个GraphQL服务器Apollo Angular提供功能齐全、可用于生产的...它专注于良好的移动开发、模块化和改进的依赖注入。angular的设计目的是全面解决开发人员的web应用程序工作流。
Angular.js作为一款流行的前端JavaScript框架,由Google开发和维护,使用MVVM(Model-View-ViewModel)架构模式,旨在简化前端开发的复杂性。在使用Angular.js进行开发时,有若干需要注意的事项和常见的问题点,接...
在Angular.js中,开发者可以利用数据绑定、依赖注入、指令、服务等核心特性来构建功能丰富的Web应用。数据绑定允许视图和模型之间的自动同步,依赖注入简化了组件之间的通信,而指令则扩展了HTML,使其能够表达更...