Can Do More Than You Think With Angular

Can Do More Than You Think With  Angular
Angular Directive Selectors Can Do More Than You Think! ,If you have ever created an Angular directive before, you probably used the brackets notation as a selector.

Most of the time it’s the preferred way, but it’s not a requirement. Actually, you can get pretty creative with the selectors used in your directives.

To emphasize this, we’ll create an anchor directive that targets every external link in our template. We’ll see how we can:

  • Target native HTML elements
  • Exclude elements by use the :not pseudo-class.

NgForm Case Study

To see an example of a complex selector, lets first have a look at the NgForm directive.
ng-external-link#ngForm.ts

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

Few things are worth a comment:

  • You can target more than one selector by separate each selector with a comma
  • You can mix targeting HTML elements (like <form>) with HTML attributes (like ngForm)
  • You can use the :not pseudo-class to exclude some elements

Create the External Link Directive

We define the external link as any anchor tag that doesn’t already have the routerLink directive.

Going by the NgForm example, we can define the selector as:
ng-external-link#dir-selector.ts

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

The beautiful thing about this selector is that we don’t have to create the attribute name for something that is better described as being the opposite of something else.

We could’ve named it externalLink, but that’s just duplicating effort. It’s also pretty easy to forget to put the directive on some external links. The advantage here is that we target them all in one go.

The directive should do the following:

  • Open the link in a separate window
  • Add the rel attribute to improve performance and prevent security vulnerabilities

We can achieve both with the use of @HostBinding().
ng-external-link#complete.ts

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

  @HostBinding('target')
  @Input()
  target = '_blank';
}

Notice how we also decorate the properties with the @Input() decorator to allow for potential overrides.

Another possible implementation of this behavior would be with the @Attribute() decorator. It would bring a slight performance boost, as unlike the @Input() decorator, it is evaluated only once. That means that subsequent change detection runs wouldn’t check the rel and target properties.

To learn more about this technique, check out this awesome article.

Testing the Directive

Let’s create simple navigation that points to some external URLs:
ng-external-link#example-nav.html

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

If you open up the Chrome Dev Tools you will see the following:

Victorious! The directive works with no extra attribute selectors needed.

Summary

In this article, we have learned that you don’t have to use the attribute selector when working with Angular directives. We’ve examined the ngForm directive, and used it as an example to implement our own custom external link directive.

Recommended Courses:

Angular 2 Firebase - Build a Web App with Typescript

Angular 2 Demystified

Master Angular 2 - The No Nonsense Course

Angular 2 - The Complete Guide

Angular 2 + Rails 5 Bootcamp

Suggest:

Angular Tutorial - Learn Angular from Scratch

Web Development Tutorial - JavaScript, HTML, CSS

Test Driven Development with Angular

E-Commerce JavaScript Tutorial - Shopping Cart from Scratch

Angular and Nodejs Integration Tutorial

Javascript Project Tutorial: Budget App