需要了解Angular.js中的依赖注入

时间:2014-05-06 12:05:07

标签: javascript angularjs dependency-injection

我是Angular.js的新手,遇到了一个名为“依赖注入”的主题。阅读完文章后,我感到非常困惑。

按照文档, 依赖注入(DI)是一种角度化的方法,用于组织组件,模块和变量如何加载到角度应用程序的各个部分。

以下是控制器依赖注入的示例:

//the controller definition
var Ctrl = function($scope, $http, $location) 
{
  //now you can use any of the injected variables

  //to change the URL after something has happened then you can use $location
  $location.path('/path/to/new/page');
}
  //and now the injection of the variables
  Ctrl.$inject = ['$scope','$http','$location'];

我想“Ctrl.$inject = ['$scope','$http','$location'];”这就是依赖注入的结果。

但我需要了解它,它的作用以及它是如何有用的?

感谢。

2 个答案:

答案 0 :(得分:2)

依赖注入允许您执行多项操作,首先它允许您仅在controllerfactoryservice等中指定所需内容。

您有很多预先选择的选项,但注入也允许您将第三方Angular模块合并到您的项目中。

例如,假设您想要使用动画和路由,但是您希望使用ui-router而不是ngRoute,而不是将它们注入到应用实例中。

var myApp = angular.module('myApp', ['ui.router', 'ngAnimate']);

现在假设你有第一个控制器设置。

但是假设您有一个服务要在该控制器中使用,该服务器使用promises处理所有的ajax调用。

首先,设置服务时会注入$http来发出服务器请求,$q代表承诺。

// It is important to note that not all modules have a scope, 
// so injecting scope into this service would cause a fatal error, 
// it is important to become familiar with what baked in modules allow for 
// injections.
myApp.service('myAjax', function ($http, $q) {
    return {
        getUsers: function () {
            var q = $q.defer();
            $http.get('my/url/path').success(function (results) {
                // We got a successful response so pass on the results
                q.resolve(results);
            }).error(function (errorResults) {
                // Something went wrong, let's pass that along
                q.reject(errorResults);
            });
            return q.promise;
        }
    }    
});

现在我们已经进行了服务设置,我们会将其注入我们的控制器中,以便我们可以轻松地使用它来获取用户或执行我们在那里声明的任何其他内容:

// Note that I am demonstrating a different injection approach, this is actually the recommended approach
myApp.controller('myController', ['$scope', 'myAjax', function ($scope, myAjax) {
    // call our service
    myAjax.getUsers().then(
        function (results) {
            // Here we are using our controller $scope injection to 
            // bind to the html
            $scope.users = results;
        },
        function (error) {},
    )
}]);

修改

$inject$injector的一部分,您可以找到more information here

$injector获取已注入的所有内容的实例,$inject只允许您设置注入参数。 $injector在幕后运行。

Here is a snippet from the angular source on github - Line 1238

angular.module('ngAppStrictDemo', [])
// BadController will fail to instantiate, due to relying on automatic function annotation,
// rather than an explicit annotation
    .controller('BadController', function($scope) {
        $scope.a = 1;
        $scope.b = 2;
    })
    // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,
    // due to using explicit annotations using the array style and $inject property, respectively.
    .controller('GoodController1', ['$scope', function($scope) {
        $scope.a = 1;
        $scope.b = 2;
    }])
    .controller('GoodController2', GoodController2);
function GoodController2($scope) {
    $scope.name = "World";
}
GoodController2.$inject = ['$scope'];

答案 1 :(得分:0)

我想分享一下我认为DI的一个非常好的例子。我从Angular.js文档中获取了this示例。

angular.module('xmpl.service', [])

  .value('greeter', {
    salutation: 'Hello',
    localize: function(localization) {
      this.salutation = localization.salutation;
    },
    greet: function(name) {
      return this.salutation + ' ' + name + '!';
    }
  })

  .value('user', {
    load: function(name) {
      this.name = name;
    }
  });

angular.module('xmpl.directive', []);

angular.module('xmpl.filter', []);

angular.module('xmpl', ['xmpl.service', 'xmpl.directive', 'xmpl.filter'])

  .run(function(greeter, user) {
    // This is effectively part of the main method initialization code
    greeter.localize({
      salutation: 'Bonjour'
    });
    user.load('World');
  })

  .controller('XmplController', function($scope, greeter, user){
    $scope.greeting = greeter.greet(user.name);
  });

此代码为指令,过滤器和服务定义了一个单独的模块。 如文档中所述:

  

运行块是Angular中与main方法最接近的东西。

因此,xmpl模块有3个依赖项,使用DI注入。