AngularJS 依赖注入

Angular JS 模块的概念和依赖注入分析

部分英文参考: Understanding Dependency Injection
部分中文参考:Angualr JS 模块化与依赖注入

Angular JS 使用模块化的组织方式,和依赖注入的设计。这使得模块之间耦合度较低,模块更容易复用,同时支持声明式的编程风格。

模块概念

1
angular.module('(这里声明模块的名字)', ['(这里列出该模块所依赖的其它模块的名字', ''..])

Module 依赖: 在声明一个模块时,需要给出依赖模块的列表。同时这些模块对应的JS需要在HTML中加以引入。一个模块中,默认引入了 Service, Directive 和 Filter模块。

  • 区分Module依赖和Service依赖:
    ​ 在声明Controller, Service, Directive 和 Filter的工厂方法中,把依赖的Service直接放到参数列表中,Angular 的 $injector 会自动注入生成这些Service。

依赖注入

​ 在Angular中, Directive, Service, Filter, Controller都是以工厂法的方式给出,而工厂方法的参数名对应着(与其相同)该工厂方法所依赖的Service。

​ 以Controller为例,有两种声明方式:

  1. 不使用字符串数组

    1
    2
    3
    app.controller('aCtrl', function($scope, $http) {
    //some code
    })

    在上述的function执行之间,Angualr $injectro 会生成一个 scope 实例和 $http 实例,并传入该方法。如果你希望对JS进行压缩处理,那么参数名称可能会发生变化,Angular的 $injector 则不能正确地把这个控制器所依赖的Service注入

  2. 使用字符串数组的形式来声明依赖项。(字符串常量不会被压缩) :

    1
    2
    3
    app.controller('aCtrl', ['$scope', '$http', function($scope, $http){
    //some code
    }])

另外,还可以同时设置 $injector 来显示地声明所依赖的Service:

1
2
3
4
5
6
var worldCtrl = function($scope, $http) {
// some code
}

worldCtrl.$inject = ['$scope', 'http'];
app.controller('worldCtrl', worldCtrl);

constant方法

注入器($injector)

注入器负责
每个Angular JS应用都有唯一一个`$injector`,当应用启动的时就会生成一个,你可以通过将 `$inject` 注入到任何可以注入函数中来得到它 (`$inject` 知道如何注入它自己)

我们不能在 constantvalue 中注入任何东西。因为 constantvalue 总是返回一个静态值,它们不会被注入器调用。

控制器($controller)

控制器可以被注入,但是控制器本身是不能被注入到任何东西里去的。这是因为控制器不是通过Provider创建的。但Angular JS内部有一个` $controller` 服务器,用来负责初始化你的控制器。比如说,当你调用 `myMod.controller(...)` 这个控制器时,其实我们在访问这个服务器的provider。