脚本宝典收集整理的这篇文章主要介绍了Angular开发者指南(七)依赖注入,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
依赖注入
依赖注入(DI)是一种软件设计模式,处理组件如何获取其依赖关系。
AngularJS注入器子系统负责创建组件,解析它们的依赖关系,并根据请求将它们提供给其他组件。
使用依赖注入
DI遍布AngularJS。 可以在定义组件或为模块提供运行和配置块时使用它。
诸如服务,指令,过滤器和动画之类的组件由注入工厂方法或构造函数定义。 这些组件可以注入“服务”和“值”组件作为依赖关系。
控制器由构造函数定义,可以使用任何“服务”和“值”组件作为依赖关系注入,但是它们也可以提供特殊的依赖关系。
run方法接受一个函数,它可以注入"service","value"和"constant"组件作为依赖。 请注意,不能将"PRoviders"注入运行块。
config方法接受一个函数,它可以注入"provider"和"constant"组件作为依赖。 请注意,无法将“服务”或“值”组件注入配置。
工厂方法
定义指令,服务或过滤器的方式是使用工厂函数。 工厂方法使用模块注册。 推荐的工厂声明方式是:
Angular.module('myModule', [])
.factory('serviceid', ['depService', function(depService) {
// ...
}])
.directive('directiveName', ['depService', function(depService) {
// ...
}])
.filter('filterName', ['depService', function(depService) {
// ...
}]);
模块方法
我们可以通过调用config和run方法指定要在模块的配置和运行时运行的函数。 这些函数是可注入的依赖关系,就像上面的工厂函数。
angular.module('myModule', [])
.config(['depProvider', function(depProvider) {
// ...
}])
.run(['depService', function(depService) {
// ...
}]);
控制器
控制器是“类”或“构造函数”,它们负责提供支持模板中的声明性标记的应用程序行为。 推荐的声明控制器的方法是使用数组符号:
someModule.controller('MyController', ['$scoPE', 'dep1', 'dep2', function($scope, dep1, dep2) {
...
$scope.aMethod = function() {
...
}
...
}]);
与服务不同,应用程序中可能有许多相同类型的控制器实例。
此外,对控制器提供附加的依赖性:
$scope:控制器与DOM中的元素相关联,因此提供对该作用域的访问。 其他组件(如服务)只能访问$rootScope服务。
resolves:如果将控制器实例化为路由的一部分,则作为路由的一部分解析的任何值都可用于注入到控制器中。
依赖注解
AngularJS通过注入器调用某些功能(如服务工厂和控制器)。 需要注解这些函数,以便注入器知道要注入到函数中的服务。 有三种方法用服务名称信息注解代码:
使用内联数组注解(首选)
使用$inject属性注解
隐含地从函数参数名称(有警告)
内联数组注解
这是注解应用程序组件的首选方式。 这是文档中的示例如何编写。
例如:
someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) {
// ...
}]);
这里我们传递一个数组,其元素由一个字符串列表(依赖项的名称)和函数本身组成。
当使用这种类型的注解时,注意保持注解数组与函数声明中的参数同步。
$inject属性注解
为了允许简写重命名函数参数并仍然能够注入正确的服务,该函数需要使用$inject属性注解。 $inject属性是要注入的服务名称的数组。
VAR MyController = function($scope, greeter) {
// ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);
在这种情况下,$inject数组中的值的顺序必须与MyController中的参数的顺序匹配。
就像数组注解一样,你需要注意保持$inject与函数声明中的参数同步。
隐式注解
注意:如果计划缩小代码,你的服务名称将被重命名并破坏你的应用程序。
someModule.controller('MyController', function($scope, greeter) {
// ...
});
给定一个函数,注入器可以通过检查函数声明并提取参数名称来推断要注入的服务的名称。 在上面的例子中,$scope和greeter是需要注入到函数中的两个服务。
这种方法的一个优点是没有与函数参数保持同步的名称数组。 可以自由地重新排序依赖项。
但是这个方法不能使用JavaScript minifiers / obfuscators,因为他们会重命名参数。
像ng-annotate这样的工具可以在应用程序中使用隐式依赖关系注解,并在缩小之前自动添加内联数组注解。 如果你决定采取这种方法,你可能想使用ng-strict-di。
由于这些注意事项,我们建议避免使用此样式的注解。
使用严格依赖注入
可以在与ng-app相同的元素上添加ng-strict-di指令以选择进入严格DI模式: