📜 ⬆️ ⬇️

Angularjs guidelines for beginners. Part 2

In my opinion, directives are the main highlight of the Angularjs declarative style. However, if you open user comments in the Angularjs official documentation section on directives , you will see that the most popular one is : “Please rewrite the documentation, make it more accessible and structured. It’s hard for a novice developer on Angularjs to figure out ”(“ Please rewrite a clearer well structured documentation of directives., It is difficult to disagree with this, the documentation is still damp and in some moments it is necessary to make great efforts to understand the logic and essence of the functional. Therefore, I offer you my free retelling of this chapter in the hope that it will save time for some people, and I also count on your support and participation in the comments. So let's go!
Part 1



Template and TemplateUrl

Continuing the conversation about directives, it should be noted that the directives are essentially modules, if we ignore the terminology of Angularjs. That is, ideally, they should be independent interface elements with their own functionality and markup. The markup can be set directly in the Template parameter or stored in a separate file, the URL of which is specified in TemplateUrl:

[ jsFiddle ]
angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"<span>Hello Habr!</span>" /*  */ templateUrl:"helloHabr.html" } }); 

helloHabr.html
 <span>Hello Habr!</span> 

In this case, if the template is loaded, the functions Compile and Link are executed after loading.
')
A useful addition in the comments

Scope

The Scope parameter defines the scope within the directive. Several options are possible:

Do not specify scope at all. Then the directive, roughly speaking, works directly in the scope of the controller. That is, all controller variables are equal to directive variables.

[ jsFiddle ]
 <div ng-app="helloHabrahabr"> <div ng-controller="forExampleController"> {{hello}} <span habra-habr></span> </div> </div> 

 function forExampleController($scope){ $scope.hello="Hello Habr!"; } angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"<input ng-model='hello'>{{hello}}" } }); 

Another variant. Scope = true. In this case, the scope will be inherited. That is, the fields specified in the parent scope will also be displayed in the scope directives, but all changes will be local:

[ jsFiddle ]
 function forExampleController($scope){ $scope.hello="Hello Habr!"; } angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"<input ng-model='hello'>{{hello}}", scope:true } }); 


Finally, the most interesting option. Set an isolated scope. That is, scope, which by default is completely independent of the context of the calling directive. To do this, simply specify the scope as an empty object {} :

[ jsFiddle ]

 angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"<input ng-model='hello'>{{hello}}", scope:{ } } }); 


Then there are several options for working with such an isolated scope. But they all boil down to the same principle. In the object that we declared for scope, some variable directive is specified as the name of the property on the left, and the name of the DOM attribute with one of three characters at the beginning: @ / = / &. That is, like this:

 scope:{ localVar1:"@attrName1", localVar2:"=attrName2", localVar3:"&attrName3" } 


Or another option. Do not specify the attribute name, then it will be equal to the variable name:

 scope:{ localVar1:"@", /*localVar1:"@localVar1" */ localVar2:"=", /*localVar2:"@localVar2" */ localVar3:"&" /*localVar3:"@localVar3" */ } 


Now in order. The prefix "@" means that the attribute value will be assigned to a local variable:

[ jsFiddle ]
 <div ng-app="helloHabrahabr"> <span habra-habr="hello" some-attr="Hello Habr!"></span> </div> 

 angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"{{hello}}", scope:{ hello:'@someAttr' } } }); 


The prefix "=" means that the attribute no longer contains a string, but the name of some variable in the current Scope. And the local variable will be directly connected with it. That is, changes in the variable both inside the directive and outside will be reflected both there and there:

[ jsFiddle ]
 <div ng-app="helloHabrahabr"> <div ng-controller="forExampleController"> {{hello}} <span habra-habr some-attr="hello"></span> </div> </div> 

 function forExampleController($scope){ $scope.hello="Hello Habr!"; } angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"<input ng-model='hello'>{{hello}}", scope:{ hello:'=someAttr' } } }); 


Finally, the last "&" option assumes that the attribute contains an expression. For example, “c = a + b” or more simply “a + b”. And now your local variable becomes a function to which you can pass parameters. Parameters are passed in the object, the keys of which are the variable names in the function. In the specific case, localVar ({a: 1, b: 2}) returns three.

[ jsFiddle ]
 angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"{{helloFn({a:1,b:2})}}", scope:{ helloFn:'&someAttr' } } }); 

It is interesting that by default, if no parameters are passed to the local function, the variables will be assigned the values ​​of the corresponding variables in the parent scope. And if you specify a variable-result, then it will also be available from the outside:

[ jsFiddle ]
 <div ng-app="helloHabrahabr"> <div ng-controller="forExampleController"> a={{a}} b={{b}} parent's hello={{hello}} <span habra-habr some-attr="hello= a+b"></span> </div> </div> 

 function forExampleController($scope){ $scope.a="Hello"; $scope.b=" Habr!"; } angular.module('helloHabrahabr', []) .directive('habraHabr', function() { return { template:"default helloFn={{helloFn()}}\ custom hello={{helloFn({a:'Bye',b:'Habr'})}}", scope:{ helloFn:'&someAttr' } } }); 


Thank you all, to be continued.

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


All Articles