在Angular 4+中动态选择不带* ngIf字符串的组件

时间:2018-03-07 20:07:50

标签: angular

在我目前的项目中,我们需要一个可扩展的解决方案,这将允许我们在基于服务器端配置的多个具体组件实现之间进行选择。在不涉及太多业务细节的情况下,我们可能会有多个注册表单(RegistrationComponentA,RegistrationComponentB,RegistrationComponentC)。服务器告诉客户端我们应该使用哪种实现。

目前我们的代码可能如下所示:

<registration-a [someProp]="serverValue" *ngIf="serverSays == 'a'"></registration-a>
<registration-b [someProp]="serverValue" *ngIf="serverSays == 'b'"></registration-b>
<registration-c [someProp]="serverValue" *ngIf="serverSays == 'c'"></registration-c>

最终,我们可能有100个具体的实现,我们想要做一些更通用的事情来避免使用100行* ngIf的模板。

我想做一些事情,我可以选择在父组件本身中呈现哪个组件,但是从我正在阅读的内容中,使用ComponentFactory解决方案混乱变更检测并需要手动清理破坏

在AngularJS中,我可以操作模板并在运行中编译它,它可以正常工作,但是使用AoT,浏览器中没有编译器。 (感谢estus指出这是不正确的)。

有没有一种优雅的方法来处理这个问题,而无需手动处理变更检测和生命周期?

1 个答案:

答案 0 :(得分:0)

如果您不想手动使用组件工厂,则可以依赖新的Angular CDK library及其Portal

您可以在父组件中设置一个插槽(PortalOutlet)以在其中显示门户。想想RouterOutlet

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

门户网站可以是ComponentPortalTemplatePortal。在您的情况下,我认为您对组件1更感兴趣。

在您的代码中,您可以切换serverValue,以创建相应的门户网站。

switch(serverValue) {
  case 'a':
    this.yourPortal = new ComponentPortal(RegistrationA);
    break;
  case 'b':
    this.yourPortal = new ComponentPortal(RegistrationB);
    break;
  case '...':
    // ...
}

如果您想更好地了解CDK门户的功能,可以阅读this article关于CDK门户网站。

由于您的组件不会在模板中静态调用,因此您必须让AOT知道您的组件需要编译。为此,您必须在声明它们的模块中的entryComponents中添加此组件。