【问题标题】:Need to understand Dependency Injection in Angular.js需要了解 Angular.js 中的依赖注入
【发布时间】:2017-03-24 19:49:22
【问题描述】:

我是 Angular.js 的新手,遇到了一个名为“依赖注入”的主题。看完这篇文章我完全糊涂了。

根据文档, 在 Angular 中,依赖注入 (DI) 是一种组织如何将组件、模块和变量加载到 Angular 应用的各个部分的方法。

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

//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'];”这就是依赖注入出现的地方。

但我需要了解它的作用和用途?

谢谢。

【问题讨论】:

  • 它只是注入你想在你的控制器、工厂、服务等中使用的模块。在你的例子中,如果你没有使用$http,那么你只需从注入中省略它,如果你需要一些东西,说ngRoute参数然后你会注入$routParams等。
  • 公平警告,您将看到各种不同的注射技术。在您的示例中,您的控制器功能参数必须在顺序和内容上与 Ctr.$inject 匹配。

标签: javascript angularjs dependency-injection


【解决方案1】:

依赖注入允许你做几件事,首先它允许你在controllerfactoryservice等中只指定你需要的东西。

您有很多预置选项,但注入还允许您将第 3 方 Angular 模块合并到您的项目中。

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

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

现在假设您已经设置了第一个控制器。

但是,假设您有一个服务,您想在该控制器中使用该服务,该服务使用 Promise 处理您的所有 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'];

【讨论】:

  • $inject 是 $injector 的一部分,您可以找到更多 information here。 $injector 获取所有已注入的实例,$inject 只允许您设置注入参数
【解决方案2】:

我想分享一个我认为非常好的 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);
  });

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

Run 块是 Angular 中最接近 main 方法的东西。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-20
    • 1970-01-01
    • 2020-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多