AngularJS - 依赖注入(Dependency Injection)

点击查看AngularJS系列目录
转载请注明出处:http://www.cnblogs.com/leosx/html


依赖注入

依赖注入是软件设计模式中的一部分,用于处理组件是如何获得它说依赖的其它组件的。git

Angular的注入器子系统(Angular是由多个系统组成)是负责建立组件,解决它们之间的依赖关系,而且根据它们的须要,给它们提供所须要的组件的实例。angularjs

 

使用依赖注入

依赖注入(DI)是贯通了整个angularjs的。当这个组件定义了,或者在module的run 方法config 方法中定义了它们,你就能够在这个module的任何地方使用这个组件了。github

一、诸如:服务(service)、指令(directive)、过滤器(filter)和动画(animation)组件,都是经过注入器的工厂(factory)方法或者在构造函数中定义的。这些组件能够注入service"(服务) 或者 "value"(值)。bootstrap

二、控制器(controller)就是使用构造函数的方式进行定义的。它能够注入service"(服务) 或者 "value"(值)。设计模式

三、run 方法接收一个function函数,它里面能够注入服务(service)或者值(value)亦或常量(constant),而后能够被注入到须要它们的组件当中去(注意,这里能够定义一些常量哦!)。提示:在run 中,你不能注入“provider”哦!数组

四、config 方法接收一个function函数,它能够注入"provider" and "constant"(常量)。提示:在config 方法中,你不能够注入"service"(服务) 或者 "value"(值)。app

关于模块Modulesrun 方法和 config 方法的更多信息,请点击这里ide

 

工厂(factory)方法

使用factory来定义指令(directive),服务(service)或者过滤器(filter)。factory方法是注册在module(模块)下的。咱们推荐你这样来定义factory:函数

angular.module('myModule', [])
.factory('serviceId', ['depService', function(depService) {
  // ...
}])
.directive('directiveName', ['depService', function(depService) {
  // ...
}])
.filter('filterName', ['depService', function(depService) {
  // ...
}]);

 

模块儿(module)的方法

咱们能够指定方法在configuration(配置环境)下运行,也能够在module(模块)的运行时,经过调用config 方法和 run 方法来运行。

angular.module('myModule', [])
.config(['depProvider', function(depProvider) {
  // ...
}])
.run(['depService', function(depService) {
  // ...
}]);

 

控制器

咱们推荐以下的方式来注册一个Controller:

someModule.controller('MyController', ['$scope', 'dep1', 'dep2', function($scope, dep1, dep2) {
  ...
  $scope.aMethod = function() {
    ...
  }
  ...
}]);

 

不像服务同样,在应用程序中,相同的controller是能够有多个实例的哈。

 

依赖性的声明

在Angular中,调用一些方法都是使用注入的方式进行调用的,例如:service factory,controller。那么你就必须将它们所使用的组件给注入进去,以提供它们使用。有如下三种方式进行依赖关系的声明。

一、使用内联数组的声明方式

二、使用$inject 属性来声明

三、隐式声明方式(不推荐,而且会有警告)

1、内联数组的声明方式

这是很是好的一种声明依赖性的方式。来一个例子:

someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
  // ...
}]);

 

咱们使用一个数组,这个数组由两部分元素组成,一个用于声明依赖性的字符串集合和最后一个元素(这个元素是一个方法,用于本身的实现)。

 

2、$inject 属性进行声明

直接上个例子:

var MyController = function($scope, greeter) {
  // ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);

 

须要注意的是,$inject 数组中的依赖,必须与MyController控制器中的参数一 一对应。

 

3、隐式声明

注意:若是你打算使用这种方式去运行代码,你的服务的名称可能会被重命名,服务也可能会在你的应用中被玩坏。

这是最简单的一种声明方式,你只要保证你的参数名称和依赖的组件名称能对得上。

someModule.controller('MyController', function($scope, greeter) {
  // ...
});

在上面的例子当中,$scope 服务和 greeter 服务会被注入到controller里面去。这种方式的一个好处就是少了依赖性声明的数组的存在。并且能够很自由的从新排列你的依赖性。

可是,这个方法在混淆和压缩后是没有发用的。是没法正常工做的。由于这些动做都会重命名你的参数。呃呃呃……

ng-annotate 工具能够方便的让你在你的应用中使用这个隐式声明模式,由于它会在进行压缩或者混淆的时候自动把你的声明方式给改为咱们推荐的内联方式进行声明,若是你想使用这种方式,可能你须要使用ng-strict-di(严格模式)。

正由于这种方式要使用严格模式,咱们须要很当心,因此,通常咱们都不会使用这种方式。

 

使用严格的依赖注入

你能够把ng-strict-di 指令增长到ng-app 指令所在的元素上,来使得你的应用使用的是严格模式。

<!doctype html>
<html ng-app="myApp" ng-strict-di>
<body>
  I can add: {{ 1 + 2 }}.
  <script src="angular.js"></script>
</body>
</html>

 

严格模式下,若是你尝试使用隐式方式来声明的时候,就会抛异常。

angular.module('myApp', [])
.factory('willBreak', function($rootScope) {
  // $rootScope is implicitly injected
})
.run(['willBreak', function(willBreak) {
  // Angular will throw when this runs(执行到这里会报错)
}]);

若是你是使用手动方式启动应用的话,你也能够这样来使用严格模式:

angular.bootstrap(document, ['myApp'], {
  strictDi: true
});

concepts-module-injector

相关文章
相关标签/搜索