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:
:not
pseudo-class.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:
<form>
) with HTML attributes (like ngForm
):not
pseudo-class to exclude some elementsWe 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:
rel
attribute to improve performance and prevent security vulnerabilitiesWe 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.
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.
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
☞ Master Angular 2 - The No Nonsense Course
☞ Angular 2 - The Complete Guide
☞ Angular 2 + Rails 5 Bootcamp
☞ 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