Доступ к `selector` из компонента Angular 2

Я пытаюсь выяснить, как я могу получить доступ к selector что мы переходим в @Component декоратор.

Например

@Component({
  selector: 'my-component'
})
class MyComponent {
  constructor() {
     // I was hoping for something like the following but it doesn't exist
     this.component.selector // my-component
  }
}

В конечном счете, я хотел бы использовать это для создания директивы, которая автоматически добавляет атрибут data-tag-name="{this.component.selector}" так что я могу использовать запросы Selenium, чтобы надежно находить мои угловые элементы по их селектору.

Я не пользуюсь транспортиром

4 ответа

Решение

Использование ElementRef:

import { Component, ElementRef } from '@angular/core'

@Component({
  selector: 'my-component'
})
export class MyComponent {
  constructor(elem: ElementRef) {
    const tagName = elem.nativeElement.tagName.toLowerCase();
  }
}

УСТАРЕЛО См. /questions/22025613/dostup-k-selector-iz-komponenta-angular-2/22025623#22025623

Вам необходимо получить метаданные, связанные с вашим компонентом:

Важное примечание Аннотации удаляются при запуске компилятора AOT, что делает это решение недействительным, если вы предварительно компилируете шаблоны

@Component({
  selector: 'my-component'
})
class MyComponent {
  constructor() {
    // Access `MyComponent` without relying on its name
    var annotations = Reflect.getMetadata('annotations', this.constructor);
    var componentMetadata = annotations.find(annotation => {
      return (annotation instanceof ComponentMetadata);
    });
    var selector = componentMetadata.selector // my-component
  }
}

Вот альтернатива, если вам нужно имя селектора без доступа к компоненту ElementRef:

      const components = [MyComponent];

for (const component of components) {
  const selector = component.ɵcmp.selectors[0][0];
  console.log(selector);
}

Честно говоря, этот первый метод кажется довольно хакерским, и кто знает, предполагается ли, что этот ɵ предназначен только для внутреннего использования? Я думал, что включу это, чтобы, может быть, кто-нибудь пролил на это свет?

Итак, это, вероятно, более безопасный маршрут:

      constructor(private factory: ComponentFactoryResolver) {
  const components = [MyComponent];

  for (const component of components) {
    const { selector } = this.factory.resolveComponentFactory(component);
    console.log(selector);
  }
}

Начиная с Angualr v14.1 вы можете сделать это:

      @Component({
  selector: 'my-component'
})
class MyComponent {
  constructor() {
     const metadata = reflectComponentType(MyComponent);
     const selector = metadata.selector // my-component
  }
}
Другие вопросы по тегам