`

AngularJs--Dependency Injection(DI,依赖注入)

阅读更多

文章源自:http://www.cnblogs.com/lcllao/archive/2012/09/23/2699401.html

 

一、Dependency Injection(依赖注入)

  依赖注入(DI)是一个软件设计模式,处理代码如何得到它所依赖的资源。

 

  关于DI更深层次的讨论,可以参观Dependency Injectionhttp://en.wikipedia.org/wiki/Dependency_injection),Inversion of Controlhttp://martinfowler.com/articles/injection.html),也可以参观软件设计模式的书。

 

1. DI in a nutshell(简说DI

  object或者function,只能够通过以下三种方式获取他们依赖的资源:

    1) 可以通过new运算符创建依赖的资源。

    2) 可以通过全局变量查找依赖的资源。

    3) 可以通过参数传入依赖的资源。

 

  12两种方式,并不是最佳的,因为它们对依赖关系进行hard code,这使得修改依赖关系时,不是不可能,但会变得比较复杂。这对于测试来说尤其是个问题,通常在独立测试时,希望能够提供模拟的依赖资源。

 

  第3种方法相对来说最可行,因为它去除了从组件(component)中定位依赖的责任。依赖仅仅交给组件就可以了。

function SomeClass(greeter) {
     this.greeter = greeter
}

SomeClass.prototype.doSomething = function(name) {
     this.greeter.greet(name);
}

 上面的例子,SomeClass不用关心定位greeter这个依赖,它仅仅在运行时传递greeter

 

  这样是比较合适的,但它将获取依赖资源的责任交给了负责构建SomeClass的代码那里。

 

  为了管理创建依赖的责任,每一个angular应用都有一个injectorhttp://code.angularjs.org/1.0.2/docs/api/angular.injector)。injector是一个服务定位器,负责定位并创建依赖的资源。

 

  请求依赖,解决了hard code的问题,但它意味着injector需要贯穿整个应用。传递injector,会破坏Law of Demeterhttp://baike.baidu.com/view/823220.htm)。为了纠正这个问题,我们将依赖查找的责任转给injector

 

  上面说了那么多,看看下面经我修改过的例子,合并了原文的两个例子,分别在angular内、外使用inject

<!DOCTYPE HTML>
<html lang="zh-cn" ng-app="MainApp">
<head>
    <meta charset="UTF-8">
    <title>injector</title>
</head>
<body>
<div ng-controller="MyController">
    <button ng-click="sayHello()">Say Hello</button>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">
    //创建OtherModule这个module,相当于外部的module
    var otherModule = angular.module("OtherModule", []);
    //教injector如何创建"greeter"
    //注意,greeter本身需要依赖$window
    otherModule.factory("greeter", function ($window) {
        //这里是一个工厂方法,负责创建greet服务
        return {
            greet:function (text) {
                $window.alert(text);
            }
        };
    });
    //下面展示在非当前module中,通过injector调用greet方法:
    //从module中创建新的injector
    //这个步骤通常由angular启动时自动完成。
    //必须引入'ng',angular的东东
    //故意颠倒顺序,暂时证实这玩意的顺序是无所谓的。。
    var injector = angular.injector(['OtherModule','ng']);
    //请求greeter这个依赖。
    var g = injector.get("greeter");
    //直接调用它~
    g.greet("Hi~My Little Dada~");

    //这里是当前的主app,需要依赖OtherModule
    var mainApp = angular.module("MainApp", ["OtherModule"]);
    //留意Controller的定义函数的参数,在这里直接注入$scope、greeter。
    // greeter服务是在OtherModule中的
    mainApp.controller("MyController",function MyController($scope,greeter) {
            $scope.sayHello = function() {
                greeter.greet("Hello Kitty~~");
            };
        }
    );
    //ng-controller已经在背后默默地做了这个事情
    //injector.instantiate(MyController);

</script>
</body>
</html>

 注意,因为有ng-controller,初始化了MyController,它可以满足MyController的所有依赖需要,让MyController无须知道injector的存在。这是一个最好的结果。应用代码简单地请求它所需要的依赖而不需要处理injector。这样设置,不会打破Law of Demeter

 

二、Dependency Annotation(依赖注释,说明依赖的方式)

 

  injector如何知道什么服务需要被注入呢?

 

  应用开发者需要提供被injector用作解决依赖关系的注释信息。所有angular已有的API函数,都引用了injector,每一个文档中提及的API都是这样。下面是用服务名称信息注释我们的代码的三个等同的方法。

 

1. Inferring Dependencies(隐含依赖)

  这是获取依赖资源的最简单的方式,但需要假定function的参数名称与依赖资源的名称一致。

function MyController($scope, greeter) {
     ...
}

 函数的injector,可以通过检查函数定义并提取函数名称,猜测需要注入的service的名称(functionName.toString()RegExp)。在上面的例子中,$scopegreeter是两个需要被注入到函数的服务(名称也一致)。

 

  虽然这样做很简单,但这方法在javascript混淆压缩后就行不通了,因为参数名称会被改变。这让这个方式只能对pretotyping产品可用性原型模拟测试法,http://www.pretotyping.org/http://tech.qq.com/a/20120217/000320.htm)和demo应用有作用。

 

2. $inject Annotation$inject注释)

 

  为了允许脚本压缩器重命名函数的方法后,仍然能够注入正确的服务,函数必须通过$inject属性来注释依赖。$inject属性是一个需要注入的服务的名称的数组。

var MyController = function(renamed$scope, renamedGreeter) {
     ...
}
//这里依赖的东东,如果不在当前的module中,它还是不认识的。
//需要在当前module中先依赖对应的module。跟之前的例子差不多。但我不知道这是不是正确的方法。
MyController.$inject = ['$scope', 'greeter'];

 需要小心的是,$inject的顺序需要与函数声明的参数顺序保持一致。

  这个注释方法,对于controller声明来说是有用的,因为它与函数一起指定注释信息。

3. inline Annotation(行内注释)

  有时候,不方便使用$inject注释的方式,例如注释directive的时候。

  例如:

someModule.factory('greeter', function($window) {
    ...;
});

 因为需要临时变量(防止压缩后不能使用),所以代码会膨胀为:

var greeterFactory = function(renamed$window) {
    ...;
};
greeterFactory.$inject = ['$window'];
someModule.factory('greeter', greeterFactory);

 由于这样(代码膨胀),angular还提供了第三种注释风格:

someModule.factory('greeter', ['$window', function(renamed$window) {
     ...;
}]);

 记住,所有注释风格都是等价的,可以被用在支持injectionangular中的任何地方。

 

三、Where can I user DI

  DI遍及整个angular。它通常使用在controllerfactory方法中。

1. DI in controllers

  controller是负责(描述)应用行为的类。建议的controller声明方法是:

var MyController = function(dep1, dep2) {
     ...
}
MyController.$inject = ['dep1', 'dep2'];
MyController.prototype.aMethod = function() {
     ...
}

 2. Factory methods

  factory方法是负责创建大多数angular对象。例如directiveservicefilterfactory方法注册在module中,建议的factory声明方法是:

angualar.module('myModule', []).
    config(['depProvider', function(depProvider){
      ...
    }]).
    factory('serviceId', ['depService', function(depService) {
      ...
    }]).
    directive('directiveName', ['depService', function(depService) {
      ...
    }]).
    filter('filterName', ['depService', function(depService) {
      ...
    }]).
    run(['depService', function(depService) {
      ...
}]);

 

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    Angularjs-master.zip

    3. **依赖注入**(Dependency Injection, DI):AngularJS的DI机制允许开发者轻松获取并管理所需的服务,如$http服务用于处理HTTP请求,$scope服务用于连接控制器和视图。这种模式使得代码更易于测试和维护。 4. **...

    AngularJs Dependency Injection(DI,依赖注入)

    AngularJS的依赖注入(Dependency Injection,简称DI)是一种软件设计模式,用于管理应用程序中的对象如何获取它们所需的依赖。依赖注入的主要目标是降低组件之间的耦合,使得代码更加灵活、可测试和可维护。 1. ...

    babel-plugin-angularjs-annotate:将Angular 1.x依赖项注入注释添加到ES6代码

    将Angular 1.x DI注释添加到Babel正在处理的ES5 / ES6代码中,并支持显式注释( /* @ngInject */ )和典型的Angular代码模式的自动(隐式)注释。 与ES5,移植ES6和原始ES6来源完全兼容。 与独立的ng-annotate工具...

    angularjs-chapter5-示例.rar

    此外,AngularJS的依赖注入(Dependency Injection, DI)机制也是其一大亮点。这一机制使得组件可以轻松获取到它们所需的依赖,无需关心这些依赖是如何被创建或管理的。在第五章的示例中,你可能会看到如何定义服务...

    AngularJS-Cheat-Sheet

    依赖注入(Dependency Injection,DI)是AngularJS解决代码耦合问题的关键机制。它允许开发者声明所需的依赖,并由框架自动注入,无需手动创建对象。这简化了代码,提高了测试性。在AngularJS中,服务(如 `$http` ...

    angularjs-chapter4-示例.rar

    8. **依赖注入(Dependency Injection)**:AngularJS的DI系统自动为我们的组件提供所需的依赖,简化了代码的编写和测试。在示例中,你将看到如何声明和注入服务,以及如何在控制器中使用它们。 通过分析和实践...

    angularjs-master

    3. **依赖注入**:AngularJS 的依赖注入(Dependency Injection,DI)机制允许组件轻松获取所需的依赖服务,如 `$http` 用于HTTP请求,`$scope` 用于管理作用域内的数据。这提高了代码的可测试性和可维护性。 4. **...

    Dependency Injection with AngularJS

    标题《AngularJS中的依赖注入》指向的知识点,聚焦于AngularJS框架中一种特定的软件设计模式——依赖注入(DI)。依赖注入是一种编程技术,允许我们通过外部方式而非硬编码来管理对象间的依赖关系。这意味着对象的...

    angularjs-1.3.10

    2. **依赖注入**:AngularJS的依赖注入(Dependency Injection, DI)系统使得服务、指令、控制器等组件的创建和管理变得更加容易。开发者只需声明所需的依赖,而无需关心它们如何被实例化或查找。 3. **指令**:...

    angularjs-app:iTechArt的测试应用程序

    - **依赖注入**:AngularJS的依赖注入(Dependency Injection, DI)机制简化了代码的编写,使得组件之间可以轻松共享服务。在"angularjs-app-master"文件中,我们可以找到被注入的服务,如$http、$scope等,它们提供...

    AngularJS- 1.3.15

    依赖注入(Dependency Injection, DI)是AngularJS的另一个关键特性。它允许开发者声明所需的外部服务或对象,而无需关心如何实例化它们。AngularJS会自动管理和提供这些依赖,降低了组件间的耦合度,使得代码更易于...

    AngularJs-1.3.10

    AngularJS的依赖注入(Dependency Injection,DI)机制简化了对象间的依赖关系。在1.3.10中,你可以通过注解来声明服务、控制器等的依赖,使得代码更加清晰,同时也方便单元测试。 ### 4. 直接ives AngularJS的指令...

    AngularJS-Services-InDepth:AngularJS-服务-深度BookLogger

    它们通过依赖注入(Dependency Injection, DI)机制被引入到应用程序的不同部分,降低了代码之间的耦合度,提高了代码的可维护性和可测试性。 ### 2. 服务的类型 AngularJS 提供了多种方式来创建和注册服务,主要...

    angularjs-simple-sample:angularjs 的简单演示

    接下来,我们来看看依赖注入(Dependency Injection,DI)。AngularJS 使用 DI 来管理对象之间的依赖关系,使得代码更易于测试和维护。通过注解或服务提供者,我们可以轻松获取所需的服务,如 `$http` 用于发送 ...

    angularjs-robozzle:AngularJS (1.3.0-snapshot) 一个最喜欢的益智网站的 SVG 实现。 工作正在进行中

    依赖注入(Dependency Injection,DI)机制使得这些服务能轻松地在不同的组件之间共享,降低了代码耦合度,提高了可测试性和可维护性。 **总结** “angularjs-robozzle”项目展示了如何利用AngularJS 1.3.0-...

    AngularJS-App:AngularJS 的基础项目

    其次,AngularJS的依赖注入(Dependency Injection,DI)机制是另一个重要特性。它允许开发者声明所需的服务,而无需关心这些服务是如何创建或如何找到的。AngularJS会自动管理这些依赖关系,使得代码更加模块化和可...

    angularjs-demo:学习angularjs

    3. **依赖注入**:AngularJS 的依赖注入(Dependency Injection,DI)机制能帮助开发者轻松管理对象间的依赖关系,无需手动实例化或查找依赖。只需声明所需的依赖,AngularJS会自动注入,提高代码可测试性和可维护性...

    SPA-AngularJS-Project:带有 AngularJS 考试项目的 SPA

    AngularJS的依赖注入(Dependency Injection,DI)机制允许开发者轻松获取和管理应用中的服务、工厂、控制器等对象,无需手动实例化或管理它们的生命周期。这有助于提高代码的可测试性和可维护性。 **模块化** ...

    AngularJS-examples:这个 repo 是为使用 Angulular JS、Bootstrap 和其他工具而创建的

    - **依赖注入**:AngularJS通过DI(Dependency Injection)系统管理组件间的依赖关系,简化代码并提高可测试性。 - **控制器**:用于扩展视图逻辑,但现代Angular(AngularJS 2+)推荐使用服务和服务提供者。 - *...

Global site tag (gtag.js) - Google Analytics