'Angular - Get the selector name of the directive
I created a directive with multiple selectors, so I can access the same directive with different selectors. What I'm trying to achieve is to get the selector name that called the directive in my directive.
The following code will explain this even better:
So this is my multi-selector directive:
import { Directive, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';
const inputs = [
'someSelector.A', 'someSelector.B'
];
const selector = `
[someSelector.A], [someSelector.B]
`;
@Directive({ selector, inputs })
export class MyDirective implements OnInit {
constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }
ngOnInit() {
// I need to know here what is the current selector:
// Is it: "someSelector.A" or "someSelector.B"?
}
}
And this is how I would like to call the directive in the HTML:
<element *someSelector.A></element>
<!-- Or: -->
<element *someSelector.B></element>
Solution 1:[1]
Okay, so the way that flex is doing it, is that they are passing the inputs to the decorator, then the variables are generated on the directive. If the directive is not passed to the html element it is undefined on the directive inputs. It looks like this:
export interface DirectiveAB {
'someSelector.A': string;
'someSelector.B': number;
}
type Selectors = 'someSelector.A' | 'someSelector.B';
const inputs = ['someSelector.A', 'someSelector.B'];
@Directive({ selector: '[someSelector.A], [someSelector.B]', inputs })
export class DirectiveAB implements OnInit {
ngOnInit() {
console.log(this.hasSelector('someSelector.A'));
console.log(this.hasSelector('someSelector.B'));
}
hasSelector(selector: Selectors) {
return typeof this[selector] !== 'undefined'
}
}
<!-- prints true for "A"; false for "B" -->
<div someSelector.A></div>
<!-- prints false for "A"; true for "B" -->
<div someSelector.B></div>
You could separate the directives into two and extend a root directive. This is really how directives should be used if you want to have different functionality for a different selector.
import { Directive } from '@angular/core';
@Directive({ selector: '*' })
export class DirectiveRoot implements OnInit {
ngOnInit() {
console.log(this);
if (this instanceof DirectiveA) {
console.log('Directive A!');
}
}
}
@Directive({ selector: '[someSelector.A]' })
export class DirectiveA extends DirectiveRoot {}
@Directive({ selector: '[someSelector.B]' })
export class DirectiveB extends DirectiveRoot {}
<!-- prints DirectiveA to the console -->
<div someSelector.A></div>
<!-- prints DirectiveB to the console -->
<div someSelector.B></div>
Another option is to look at the element itself and check to see if the attribute exists:
@Directive({ selector: '[someSelector.A], [someSelector.B]' })
export class DirectiveAB implements OnInit {
constructor(private readonly ref: ViewContainerRef) {}
ngOnInit() {
console.log(this.ref.element.nativeElement.hasAttribute('someSelector.A'));
console.log(this.ref.element.nativeElement.hasAttribute('someSelector.B'));
}
}
<!-- prints true for "A"; false for "B" -->
<div someSelector.A></div>
<!-- prints false for "A"; true for "B" -->
<div someSelector.B></div>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
