通过将组件名称指定为输入参数,将 Angular 组件导入另一个组件

Posted

技术标签:

【中文标题】通过将组件名称指定为输入参数,将 Angular 组件导入另一个组件【英文标题】:Import Angular Component into another Component by specifying the component name as input parameter 【发布时间】:2021-01-01 04:02:01 【问题描述】:

我想创建一个由多个子组件组成的角度组件。最终我想创建一个大型的可重用树组件,其节点具有不同的数据类型。对于每种数据类型,树组件导入指定节点应如何显示的子组件。用户应该能够指定一个自定义组件来覆盖特定数据类型的默认组件。像这样的导入语法会很好:

<app-tree [customDateComp]="CustomDateComponent"></app-tree>

这可能是简化后的 tree.component.html

<ng-container *ngIf="!customDateComp">
 <app-default-date></app-default-date>
</ng-container>
<ng-container *ngIf="customDateComp">
  customDateComp 
</ng-container>

当然这还不行,因为组件是用语法导入的。下面的方法也不起作用,因为 angular 转义了它:

<app-tree [customDateComp]="'<app-custom-date></app-custom-date>'"></app-tree>

示例代码可以在这里找到: https://stackblitz.com/edit/angular-ivy-xghj5f?file=src/app/app.component.html

有没有人知道如何通过将组件名称指定为输入参数来将 Angular 组件导入其他组件?或者有没有更好的方法来覆盖第三方组件的默认子组件?非常感谢!

【问题讨论】:

看看ng-content 认为它会满足你的需要 也许是dynamic-component-loader? 这能回答你的问题吗? How can I use/create dynamic template to compile dynamic Component with Angular 2.0? 【参考方案1】:

这是您的stackblitz demo 工作。

在可能的方法中,有一个门户(以及可从@angular/cdk/portal 获得的实用程序)。

基本上,这就是您所需要的:

1 - 接收组件的占位符(在本例中为 cdkPortalOutlet 设置):

<ng-template [cdkPortalOutlet]="_compPortal"></ng-template>

2 - 一个门户(_compPortal,上图)插入您的门户插座:

_compPortal = new ComponentPortal<any>(MyCustomComponent);

就是这样。

在你的情况下(你在问题中链接的 stackblitz)你可以这样做:

0 - 导入@angular/cdk/portal 模块:

import PortalModule from '@angular/cdk/portal';

@NgModule(imports: [ ... PortalModule ] ...) export class AppModule  

1 - tree.component.html

<ng-container *ngIf="!_compPortal">
 <app-date></app-date>
</ng-container>
<ng-container *ngIf="_compPortal">
  <ng-template [cdkPortalOutlet]="_compPortal"></ng-template>
</ng-container>

2 - tree.compoenent.ts

@Input() 
set customDateComp(customComp: any)
  this._compPortal = customComp ? new ComponentPortal(customComp) : null;

_compPortal: ComponentPortal<any>;

3 - app.component.ts

// Notice this is not `_comp: CustomDateComponent`.
// I'm setting up an attribute that receives the type so I can 
// make it available on the template
_comp = CustomDateComponent;

4 - app.component.html

<app-tree [customDateComp]="_comp"></app-tree>

【讨论】:

【参考方案2】:

您可以使用动态组件加载器https://angular.io/guide/dynamic-component-loader

【讨论】:

以上是关于通过将组件名称指定为输入参数,将 Angular 组件导入另一个组件的主要内容,如果未能解决你的问题,请参考以下文章

Angular 5 - 将组件的名称实例化为字符串

将 Angular 组件从许多输入/输出重构为单个配置对象

将图像名称传递给vue组件时找不到图像

Angular - 将输入传递给 ng-content 组件

通过将参数作为组件名称返回 JTable 的函数

Angular 组件命名限制 - “选择器 [您的组件名称] 无效”