10

I'm wondering what the use cases are for these two methods of creating a controller:

Using ngController:

myApp.controller('myController', ['$scope', function ( $scope ) {

}]);

Constructing the controller within a directive with the controller attribute:

myApp.directive ( 'myDirective', [ '$window', function( $window ) {
    return {
        restrict: 'A',
        controller: [ '$scope', function( $scope ) {

        }],
        link: function( scope, element, attrs ) {

        }
    };
}]);

Is there any reason you wouldn't construct the controller within a directive if they were both invoked on the same element?

Is it simply a question of how widely used / complex the controller is?

2
  • What do you mean Constructing the controller within , from scratch or from empty controller? Commented Oct 7, 2013 at 13:21
  • Hope the edit makes it clearer. Commented Oct 7, 2013 at 13:30

4 Answers 4

8

The reason to use directive controller is condensed in one sentence:

To create reusable components

Directive controller should contain logic of the component that could be reused. Using directive controller together with isolate scope is the way to create reusable components.

Take a paginator as an example: a paginator needs some logic to notify other component (a grid for example) of the current selected page changed so that the grid can update accordingly. These logic could be written inside directive controller to be reused. When using together with isolate scope, this scope is not tight to application controller'scope and it's easy for you to configure pageSize to bind to any property of the application controller's scope.

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

Comments

5

There is a subtle difference between a normal controller ( one created using ng-controller or routes ) and a directive controller.

  1. A Directive controller is allowed to inject $element. Note that while currently you can inject $element into a normal controller as well, its bad practice to do so.

  2. The sole purpose of a directive controller is for directive to directive communication. A very good use case is show on the main page of AngularJS for tabs component.

A directive controller allows directives to have functions. Because these controller instances can be 'required' in other directives - other directives can communicate / operate on this directive using the controller instance.

The only reason to use a controller with a directive is if you want to do some kind of directive to directive communication. For anything else you should probably stick with writing all your scope logic in the linking function.

4 Comments

I haven't created complex applications yet, but does this mean you could have an instance where you have both an ngController on an element, and a directive that has it's own controller constructor for inter-directive communication? If so, does scope get funky? Or is it the same?
The scope does not get funky. The two controllers do share the same scope. The important thing to note is that in case of a directive controller you define new emthods on the controller while in a normal controller you would ( generally ) put the functions etc on the $scope.
How do i define the methods on the controller correctly? Using this I can access the methods using the fourth argument passed into the link functions of both the parent and child directives, but as far as I can see in the docs, this fourth element is used when you require, there's no mention of its usage in the parent directive to access its own controller...
Sorry, I dint get what you meant by parent directive accessing its own controller. A directive need not access its own controller. Since both the link function and the controller have access to the scope - all communication can be done through it ( and generally there is no need to communicate between the two! ).
0

The directive controller call each time when the directive is call i mean

<directive id="1"></directive>
<directive id="2"></directive>
<directive id="3"></directive>

The directive controller call 3 time and each has own scope.

And ngController has also same nature . But ngcontroller can also reuse in other directives / html pages .

you can also put ngcontroller in directive (we assume that appCtrl define in any controller.js file)

.directive('directive',function(){
    return{
         scope:{},
         template:"<div>{{hello}}</div>",
         controller:"appCtrl"
    }
})

Comments

0

Adding some detail regarding accessing methods and values within the directive controller:

Parent directive

myApp.directive ( 'parent', [ function() {
    return {
        restrict: 'A',
        scope: {},
        controller: [ '$scope', function( $scope ) {
            //this.myVar = ''; //accessible in child directives
            //$scope.myVar = ''; //accessible in template
            $scope.myVar = this.myVar = '';
        }],
        template: '<div data-child> {{myVar}} </div>',
        link: function( scope, element, attrs ) {

            console.log( scope.myVar );

        }
    };
}]);

Child directive

myApp.directive ( 'child', [ function() {
    return {
        restrict: 'A',
        require: '^parent',
        link: function( scope, element, attrs, ctrl ) {

            console.log( ctrl.myVar );

        }
    };
}]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.