Multiple directive selectors - find which selector was used in template

Viewed 1481

I have two selectors dirA and dirNotA for my directive. The directive should proceed further based on the selector used. Is there any way to determine which selector was used within the directive?

I do not wish to have multiple directives nor a directive with parameters. I wish to have one directive with multiple selectors and to determine the course of action based on the selector used in the template.

Something like this

@Directive({
  selector: '[dirA], [dirNotA]`
})
class DirectiveA implement OnInit {
  ngOnInit() {
    // here we detected which selector was used
    if (dirASelector) {
      ...
    }

  }
}

Any ideas how can get this information in the directive itself?

3 Answers

You can use inheritance.

class DirectiveAOrNotA implements OnInit {
// common logic here
}

@Directive({
  selector: '[dirA]`
})
export class DirectiveA extends DirectiveAOrNotA {
// differences here
}

@Directive({
  selector: '[dirNotA]`
})
export class DirectiveNotA extends DirectiveAOrNotA {
// differences here
}

if you want just one directive you could use setters for inputs named after all the selectors and in their bodies set some private prop accordingly

probably a weird example but imagine something like this

@Directive({
  selector: "[addQA],[addTestId]",
})
export class AddQADirective implements OnInit, OnChanges {
  private value: string = "";

  @Input() public customName: string = "";

  @Input() public set addQA(value: string) {
    this.customName = "qa";
    this.value = value;
  }

  @Input() public set addTestId(value: string) {
    this.customName = "test";
    this.value = value;
  }

  constructor(private element: ElementRef<HTMLElement>) {}

  public ngOnInit(): void {
    if (!this.value) {
      return;
    }
    const attrName = `data-${this.customName}`;
    this.element.nativeElement.setAttribute(attrName, this.value);
  }
}

You could use ElementRef and check for the selector in it's attributes.

Directive

import { Directive, OnInit, ElementRef } from '@angular/core';

@Directive({
  selector: '[dirA], [dirNotA]'
})
class DirectiveA implement OnInit {
  constructor(private _elRef: ElementRef) { }

  ngOnInit() {
    if ((this._elRef.nativeElement.attributes).hasOwnProperty('dirA')) {
      // selector is 'dirA'
    } else if ((this._elRef.nativeElement.attributes).hasOwnProperty('dirNotA')) {
      // selector is 'dirNotA'
    }
  }
}

Working example: Stackblitz

Related