Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular component controller injection issue

Tags:

angularjs

Angular 1.5 introduced components (special kind of directive)

For directive we can write:

app.directive('myDirective',
            ['$timeout','$mdToast','$rootScope',  // <-- injection
            function ($timeout, $mdToast,$rootScope) {
return {
   link: {},
    //...
        }
    }

How can we write injection for components?

For sure I can write, something like:

app.component('myComponent',  {
            restrict: 'E',
            bindings: {
                data: '='
            },
            templateUrl: 'template.html',
            controllerAs: 'vm',
            controller: 'myComponentCtrl'
    });

and:

app.controller('myComponentCtrl', 
    ['$scope',  '$timeout', 
     function ($scope, $timeout) {
   // ....
}]); 

But I want to write build-in controller, like:

app.component('myComponentCtrl', {
  templateUrl: 'template.html',
  controller: function($scope, $timeout) {
    //...
  }
});

Above mentioned style minifying (GRUNT) will brake my code Unknown provider: aProvider <- a,

So how to write properly injection for components?

Any ideas?

The demo I use Plunker

like image 670
Maxim Shoustin Avatar asked Feb 26 '16 20:02

Maxim Shoustin


2 Answers

You need to wrap controller: function($scope, $timeout) { in the minification syntax.

I'm actually not a fan of the inline but :

app.component('myComponentCtrl', {
 templateUrl: 'template.html',
 controller: ['$scope', '$timeout', function($scope, $timeout) {
  //...
 }]
});

Cleaner form:

app.component('myComponentCtrl', {
 templateUrl: 'template.html',
 controller: myComponentCtrl
})


myComponentCtrl.$inject = ['$scope', '$timeout'];
/* @ngInject */
function myComponentCtrl($scope, $timeout) {
  //...

}

Third option is to use ng-annotate and you can remove the myComponentCtrl.$inject = ['$scope', '$timeout']; line above.

like image 129
Nix Avatar answered Oct 29 '22 11:10

Nix


You can just go ahead and use the array notation for your controller.

app.component('myComponent',  {
    restrict: 'E',
    bindings: {
        data: '='
    },
    templateUrl: 'template.html',
    controllerAs: 'vm',
    controller: ['$scope', function ($scope) {

    }]
});

What i prefer to do however is use a tool like ng-annotate on my build pipeline that automatically converts your injectables into array notation, so your source code does not need to worry about that.

like image 23
Prashant Avatar answered Oct 29 '22 10:10

Prashant