【问题标题】:Accessing `selector` from within an Angular 2 component从 Angular 2 组件中访问“选择器”
【发布时间】:2016-09-08 08:45:09
【问题描述】:

我试图弄清楚如何访问我们传递给 @Component 装饰器的 selector

例如

@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 查询通过它们的选择器可靠地找到我的角度元素。

我没有使用量角器

【问题讨论】:

    标签: angular angular2-directives angular2-components angular2-decorators


    【解决方案1】:

    过时https://stackoverflow.com/a/42579760/227299

    您需要获取与您的组件关联的元数据:

    重要提示当您运行 AOT compiler 时,注释会被剥离,如果您正在预编译模板,则此解决方案将无效

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

    【讨论】:

    • 这看起来很有希望,如果我们什么都不告诉它,Reflect.getMetadata 怎么知道它应该为MyComponent 寻找元数据?我目前在调用Reflect.getMetadata('annotations'); 时遇到错误错误是Reflect.getMetadata('annotations') VM61 angular2.sfx.dev.js:2652 Uncaught TypeError(…)getMetadata @ Reflect.getMetadata('annotations', this, 'annotations') 看起来它需要两个额外的参数
    • 通过传递 this.constructor 作为第二个参数来修正您的答案。
    • 请用它适用的 Angular 2 版本来限定这个答案 - 从 2.3.0 版开始,这似乎已经过时了
    【解决方案2】:

    使用ElementRef:

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

    【讨论】:

    • 这可能是现在唯一的方法了。较旧的(现在已损坏)方式更好,因为它不需要添加注入,并且无需实例即可访问,我在编写端到端测试时使用它以最大程度地减少重复。
    【解决方案3】:

    如果您需要选择器名称而无法访问组件的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);
      }
    }
    

    【讨论】:

    • 第一个解决方案取决于内部/私有值。但是,第二种解决方案看起来很可靠。
    猜你喜欢
    • 2017-12-14
    • 1970-01-01
    • 2017-01-24
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    相关资源
    最近更新 更多