【问题标题】:Construct component selector via an @Input通过 @Input 构造组件选择器
【发布时间】:2019-06-20 14:41:23
【问题描述】:

如何在 Angular 中以编程方式构造选择器?

假设我有一个名为 header.component 的父组件,它看起来像这样;

export class ContentHeaderComponent {
  @Input() iconName: string;
}

...我正在使用 Angular Feather 向应用程序添加图标,这需要您执行以下操作来创建图标:

<i-chevron-down></i-chevron-down>

在我的标题组件模板中,我想通过父组件将“chevron-down”传递给标签。实际上,我希望在标题组件中做这样的事情:

<i-{{ iconName }}></i-{{ iconName }}>

是否可以在 Angular 中动态构建选择器?

【问题讨论】:

  • 我不确定,但您可以尝试domSanitizer.bypassSecurityTrustHtml 方法。 this.html = domSanitizer.bypassSecurityTrustHtml(${iconName}>`);
  • 有趣的想法@epsilon。这不是世界上最安全的事情,但考虑到我只是将它用于图标......让我测试一下。

标签: angular angular-components angular-template


【解决方案1】:

如果您使用 css 或基于连字的方法,您的用例会非常简单,但是因为您的库每个图标有 1 个 comp,并且它们之间基本上没有通用接口,所以 AFAIK 有几乎没有办法将字符串映射到其对应的组件类。

cmets 中建议的方法不起作用,因为 angular 不会从经过清理的 HTML 中创建组件实例

您可以尝试以下想法:您可以传递带有所需图标的模板并将其嵌入到组件中,而不是传递图标名称。这可以按如下方式完成:

@Component({
  selector: 'foo-header'
})
export class ContentHeaderComponent {
  @Input() iconTemplate: TemplateRef<any>;
}

content-header.component.html

<ng-container *ngIf="iconTemplate">
  <ng-container [ngTemplateOutlet]="iconTemplate"></ng-container>
</ng-container>

foo.component.html

<foo-header [iconTemplate]="iconRef"></foo-header>
<ng-template #iconRef>
  <i-chevron-down></i-foo-icon>
</ng-template>

另一种方法是将图标标记直接嵌入到组件中:

@Component({
  selector: 'foo-header'
})
export class ContentHeaderComponent {}

content-header.component.html

<ng-content select="[header-icon]"></ng-content>

foo.component.html

<foo-header>
  <i-chevron-down header-icon></i-foo-icon>
</foo-header>

您可以在this article 中了解这些方法及其优缺点。

【讨论】:

  • 很好的建议。谢谢。
【解决方案2】:

不可能在 Angular 中动态创建 Angular 组件的选择器,因为 Angular 必须编译该元素。但是,您可以为 Web 组件执行此操作,方法是将 Angular 组件编译为 Angular 元素,然后将这些 Web 组件动态插入到 DOM 中。

【讨论】:

    【解决方案3】:

    使用 Renderer2 代替 @epsilon -s 答案可能更安全。

    像这样使用它:

      constructor(private renderer: Renderer2, private el: ElementRef) {}
    
      ngOnInit() {
        const icon = this.renderer.createElement('i-chevron-down')
    
        this.renderer.appendChild(this.el.nativeElement, icon)
      }
    

    您当然可以向该字符串添加任何变量。 另外不要忘记删除 OnDestroy 生命周期中的元素

    【讨论】:

      猜你喜欢
      • 2019-07-20
      • 2018-07-27
      • 2016-12-23
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      • 2010-10-03
      • 2023-02-09
      • 2021-08-13
      相关资源
      最近更新 更多