📜 ⬆️ ⬇️

Directive Controllers in AngularJS

A little bit about directive controllers. Why they are needed and how they differ from the link function.


Controller directive vs view controller

Controller declaration in directive:

 app.controller('myCtrl', function($scope, $element, $attrs) { this.name = 'myCtrl' ) app.directive('myDirective', function() { return { controller: 'myCtrl', link: function(scope, element, attrs, ctrl) { console.log(ctrl.name) //'myCtrl' } } }); 

')
Tricky question. What is the difference between the directive controller and the view controller that we specify via the ng-controller (or in another way)?

Yes, nothing. It is the same. If we use it in a directive, then the scope and element of the directive come in the $scope, $element, $attrs parameters $scope, $element, $attrs and if the template contains the scope and parameters of the element on which the ng-controller is hanging.

Hence the conclusion. If you have a bunch of similar logic in the controllers of the router or templates with ng-controller , then simply create a directive and transfer all the logic to its controller, thereby simplifying the application code.

Vs link directive controller

We understand further. In the directive definition object there is a well-known link function, which, at first glance, is no different from the controller. But the differences are still there.

First , it is called after the controller. The sequence of calls is: controller, preLink, postLink ( postLink is the link . For more information controller, preLink, postLink documentation ). The controller works even earlier than the directives of nested elements are initialized. Therefore, in $scope , for example, you can write settings for child directives.

Secondly , the link to the controller is passed to the link.

Third , the link always bound to a directive, while the controller may be shared. I think this is the key difference.

An example of using third-party controllers in a directive, so as not to break away from the code:

 <parent> <children> <baby></baby> </children> </parent> 


 app.directive('parent', function() { return { controller: 'parentCtrl', link: function(scope, element, attrs, ctrl) { console.log(ctrl); //parentCtrl.      } } }); app.directive('children', function() { return { require: '^parent', controller: 'childrenCtrl', link: function(scope, element, attrs, ctrl) { console.log(ctrl); //parentCtrl.        ,   require. //    ,      . // ,         , //     . //PS       require,     (require: ['^parent', 'children']) } } }) app.directive('baby', function() { return { restrict: 'E', require: ['^parent', '^children'], link: function(scope, element, attrs, ctrls) { console.log(ctrls); //[parentCtrl, childrenCtrl].      children      } } }) 

Living example in planker

In the controller we create an instance of the controller, in require we refer to the created instances, which makes it possible to store common data in the controller.

We can distinguish two cases of using controllers: the separation of common methods between different directives, how ngModelController in Angulyar, for example, and the use of nested directives of the parent directive, how tabs, carousels, etc. work, where there is a parent container and nested elements . If in the first case the controller works as a set of abstract methods, in the second it can store a link to the list of elements, the number of the active element, the total number of elements and other general information. Of course, the use of $scope permissible for this purpose, but, obviously, it will not be as intended, since the scope is needed primarily to bind the controller to the view, and not to share common data.

The link also contains the individual logic of the directive, so put all the code not intended for general use there.

Source: https://habr.com/ru/post/232023/


All Articles