Доступ к селектору из компонента 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 для надежного поиска моих угловых элементов по их селектору.

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


person Juan Mendes    schedule 12.05.2016    source источник


Ответы (3)


Используйте 1_:

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

@Component({
  selector: 'my-component'
})
export class MyComponent {
  constructor(elem: ElementRef) {
    const tagName = elem.nativeElement.tagName.toLowerCase();
  }
}
person Anton Poznyakovskiy    schedule 03.03.2017
comment
Это, наверное, единственный способ сделать это сейчас. Старый (теперь сломанный) способ был лучше, так как он не требовал добавления инъекции и был бы доступен без экземпляра, который я использую при написании сквозных тестов, чтобы минимизировать дублирование. - person Juan Mendes; 03.03.2017

УСТАРЕЛО См. https://stackoverflow.com/a/42579760/227299

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

Важное примечание Аннотации удаляются при запуске компилятор 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
  }
}
person Thierry Templier    schedule 12.05.2016
comment
Это выглядит многообещающе, но как Reflect.getMetadata может узнать, что он должен искать метаданные для MyComponent, если мы ему ничего не сообщаем? В настоящее время я получаю сообщение об ошибке при вызове Reflect.getMetadata('annotations'); Ошибка Reflect.getMetadata('annotations') VM61 angular2.sfx.dev.js:2652 Uncaught TypeError(…)getMetadata @ Reflect.getMetadata('annotations', this, 'annotations') Похоже, что для этого нужны два дополнительных параметра. - person Juan Mendes; 12.05.2016
comment
Исправил свой ответ, передав this.constructor в качестве второго аргумента. - person Juan Mendes; 12.05.2016
comment
Пожалуйста, укажите в этом ответе версию Angular 2, к которой он применяется - начиная с версии 2.3.0 это кажется устаревшим. - person Neoheurist; 14.12.2016

Вот альтернатива, если вам нужно имя селектора без доступа к компоненту 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);
  }
}
person Drew Payment    schedule 21.07.2021
comment
Первое решение зависит от внутренних/частных значений. Однако второе решение выглядит солидно. - person Juan Mendes; 21.07.2021