📜 ⬆️ ⬇️

Angular: unobvious directive selectors

If you have ever created Angular directives, then you probably used a structure in which brackets are used: ([]) . Such an approach, although it is most often used by him, is not the only possible one. In fact, selectors used in directives give the programmer a wide scope for creativity. In order to demonstrate this idea in action, the material, the translation of which we publish today, discusses the methodology for creating a directive designed to work with external links that are in the template. In particular, we will discuss how to find ordinary HTML elements, and, if necessary, exclude some of them from the sample, using the :not pseudo- :not .


NgForm directive


To see an example of a complex selector, take a look at the ngForm directive:

 @Directive({ selector: 'form:not([ngNoForm]):not([formGroup]),ngForm,ng-form,[ngForm]', }) 

Here you should pay attention to the following:
')

Creating a directive to work with external links


By external link, we mean the <a> tag, which does not have a routerLink directive. Considering what we found out by analyzing the previous example, the corresponding selector can be described as follows:

 @Directive({ selector: 'a:not([routerLink])', }) 

The beauty of this selector is that we don’t need to create an attribute name for something that can best be described as the opposite of an entity.

We can, for highlighting external links, use something like a directive named externalLink , but this is completely unnecessary, since this approach translates into duplication of already existing mechanisms. It is also easy to forget to add a similar directive to some external links. The strength of our method lies in the fact that, thanks to one line, we can access all external links.

The results of applying the directive to external links should look like this:


Both of these goals are achievable through the use of @HostBinding() :

 @Directive({ selector: 'a:not([routerLink])' }) export class ExternalLinkDirective { @HostBinding('rel') @Input() rel = 'noopener'; @HostBinding('target') @Input() target = '_blank'; } 

Please note that here, among other things, we decorated the properties with the help of the @Input() decorator, which, if necessary, opens up possibilities for redefinition.

Another valid implementation of such a solution may be to use the @Attribute() decorator. This approach will give a slight increase in performance, since, unlike the @Input() decorator, when using @Attribute() values ​​of the corresponding properties are calculated only once, that is, there is no constant checking of the rel and target properties in the change check loop.

Details about this technique can be found here .

Testing Directive


Create a simple navigation block containing links leading to external resources:

 <nav> <a href="https://google.com">Google</a> <a href="https://bing.com">Bing</a> <a href="https://forbes.com">Forbes</a> </nav> 

If, using the Chrome developer tools, to view the corresponding HTML code, you will see the following:


HTML code of the navigation block after applying the directive

This is exactly what we need. The directive works without the need for additional attribute selectors.

Results


From this material, you learned that, when working with Angular directives, it is not necessary to use attribute selectors. Here we first investigated the ngForm directive, and then used this knowledge to create our own directive for working with external links. We hope this technique is useful to you.

Dear readers! If you know of any non-obvious techniques of developing web projects using Angular, please tell us about them.

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


All Articles