What is the best practice for dependency injection

2019-05-30 08:52发布

问题:

So thanks to ng-annotate, now we can minify our code successfully when it looks like this:

angular.module('YeomanApp')
  .controller('YeoCtrl', function ($scope) {
   $scope.awesomeThings = [
     'HTML5 Boilerplate',
     'AngularJS',
     'Karma'
    ];
   });

Are there any advantages to this form over this form:

angular.module('YeomanApp')
  .controller('YeoCtrl', ['$scope', function ($scope) {
   $scope.awesomeThings = [
     'HTML5 Boilerplate',
     'AngularJS',
     'Karma'
    ];
   }]);

The latter explicit dependency declaration seems to be the norm, but are there any advantages or reasons to continue using it at this point?

回答1:

It depends on your project. If you are using the ngAnnotate for your project -- and it works for all your DI cases -- use it. Just be sure that all your devs follow this convention. Be aware that ngAnnotate or a similar tool is a requirement for minification.

In general, using the inline annotation seems to be preferred, as it has no dependency on a build tool like ngAnnotate. But there is no reason why using ngAnnotate should not work.

There is a third option as well

MyCtrl = function($scope) {
  $scope.awecomeThings = [...];  
} 
MyCtrl.$inject = ['$scope'];

angular.module('YourApp').controller('MyCTrl', MyCtrl);

This looks really nice if using TypeScript (maybe CoffeeScript too?)

class MyCtrl {
    static $inject = ['$scope'];
    contructor($scope: any) { // shouldn't use any, but this is just an example
        $scope.awesomeThings = [...];
    }
}

angular.module('YourApp').controller('MyCtrl', MyCtrl);


回答2:

The correct form:

angular.module('YeomanApp')
  .controller('YeoCtrl', ['$scope', function ($scope) {
     $scope.awesomeThings = [
       'HTML5 Boilerplate',
       'AngularJS',
       'Karma'
     ];
}]);

Because if you want to concatenate and minify you code at production, $scope param in controller function will transform to param a and Angular can not find $scope provider. If you use this form, providers and services storage as string, and you can write something like this .controller('YeoCtrl', ['$scope', function(a){a.awesomeThing = [...]}]

Read more here:

Angular Depency Injection



回答3:

There is no benefit to using the array notation. Writing the array notation just increases the potential for bugs. Always use the short hand version for brevity and comment anywhere you see otherwise. As you say, using ng-annotate (and ng-min prior) creates the array notation for you. 99 times out of a 100, if you're minifying your code then you will be using a task runner and therefore can just use ng-annotate. The "The correct form:" below is not advised.

The first is preferred, i.e.:

angular.module('YeomanApp')
    .controller('YeoCtrl', function ($scope) {
        $scope.awesomeThings = [
            'HTML5 Boilerplate',
            'AngularJS',
            'Karma'
        ];
    });