6

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

2 Answers 2

11

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.

Sign up to request clarification or add additional context in comments.

3 Comments

yes, 1st option is pretty ugly form, agree with ng-annotate.
I like the cleaner example but I can not comprehend it. How come you set the $inject property on myComponentCtrl before actually creating the object ? Also you are asigning the controller to a component declared before actually declaring the controller function. How will that work ? I think something is missing from the cleaner example.
@Liviu Google "javascript hoisting". TL;DR: JavaScript var and function declarations are "hoisted" to the top of the scope, so you can declare a function anywhere in your code and access it the same way as if you had declared it right up at the beginning of the current scope.
4

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.