键入检查组件

时间:2017-11-10 16:12:24

标签: angular typescript angular2-template transclusion

我想将组件类作为输入传递给另一个组件:

@Component({selector: 'dummy-comp', template:'i am dummy'});
class Dummy {}

@Component({
  selector: 'not-so-dummy',
  template:'<ng-content *ngComponentOutlet="transcluded"></ng-content>'
})
class LessDummy {
  @Input() transcluded: ???
}

我应该使用什么类型进行抄袭? Dummy不会扩展任何内容,而是使用@Component装饰器。另一方面,一种组件类型,它从Directive扩展......这是一些额外的测试:

let dummy = Dummy, component = Component;
typeof dummy // "function"
dummy.name // "Dummy"
typeof component // "function"
component.name // "DecoratorFactory"
dummy instanceof component // false

如果我理解正确,我可以使用Function作为transcluded输入的类型,但理想情况下我想缩小范围。也许我会以错误的方式解决这个问题,但这就是我想要实现的目标:

<div [ngSwitch]="getTypeOf(input)">
  <div *ngSwitchCase="'Component?'">
    <ng-content *ngComponentOutlet="input"></ng-content>
  </div>
  <span *ngSwitchCase="'string'">{{input}}</span>
  <span *ngSwitchCase="'function'">{{input()}}</span>
</div>

我完全不知道将getTypeOf函数用于什么逻辑。

修改: 根据{{​​3}}:

  

将原始构造函数的原型复制到f的原型,以确保在创建Person的新实例时,instanceof运算符按预期工作。

这可以解释为什么instanceof不起作用。

EDIT2 : 运气好Reflect

 Reflect.getMetadata('annotations',dummy)[0].selector // "dummy-comp"

1 个答案:

答案 0 :(得分:0)

看起来这样可行:

private getTypeOf(d:any): string {
  let type:string = typeof d;
  if (type === 'function') {
    let metaKeys:string = Reflect.getMetadataKeys(d);
    if (metaKeys.indexOf('annotations') > 0) {
      let annotations:string[] = Reflect.getMetadata('annotations', d);
      if (annotations.indexOf('@Component') > 0) {
        type = '@Component';
      }
    }
  }
  return type;
}

有关详细信息,请查看Reflect documentation

请注意,这在Internet Explorer上不起作用。

编辑 metadata方法文档一夜之间从MDN网站上消失,您可以查看this website而不是