簡體   English   中英

Angular - 獲取指令的選擇器名稱

[英]Angular - Get the selector name of the 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"?
  }
}

這就是我想調用 HTML 中的指令的方式:

<element *someSelector.A></element>

<!-- Or: -->

<element *someSelector.B></element>

好吧,flex 的做法是將輸入傳遞給裝飾器,然后在指令上生成變量。 如果指令未傳遞給 html 元素,則它在指令輸入中未定義。 它看起來像這樣:

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>

您可以將指令分成兩部分並擴展根指令。 如果您想為不同的選擇器提供不同的功能,這就是指令的實際使用方式。

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>

另一種選擇是查看元素本身並檢查屬性是否存在:

@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>

不太確定您要完成什么,但您可以通過幾種不同的方式檢查與選擇器匹配的輸入

@Directive({
  selector: '[myDirective.A], [myDirective.B]',
})
export class MyDirective {
  @Input('myDirective.A')
  inputA;

  @Input('myDirective.B')
  inputB;

  constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }

  ngOnInit() {
    if (this.inputA !== undefined) {
      // used directive A
    } else if (this.inputB !== undefined) {
      // used directive B
    }
  }
}

或者你可以在 setter 中檢查它:

@Directive({
  selector: '[myDirective.A], [myDirective.B]',
})
export class MyDirective {
  @Input('myDirective.A')
  set inputA(valueA) {
    // will only run if A selector used
  }

  @Input('myDirective.B')
  set inputB(valueB) {
    // will only run if B selector used
  }

  constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) { }

}

在模板中:

<div *myDirective.A></div>
<div *myDirective.B></div>

https://stackblitz.com/edit/angular-92yazy?file=src%2Fapp%2Fapp.component.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM