选择要在Angular 2中动态显示的组件

时间:2019-04-18 19:23:47

标签: angular

我有很多组件,只有特定组件会显示(这将基于从API接收到的一些数据)。我想避免使用*ngSwitch*ngIf,您是否知道该怎么做?我想这与ng-containerng-template有关,但是我真的不知道该如何处理,谢谢帮助!

2 个答案:

答案 0 :(得分:0)

我实际上已经做了很多工作,需要在运行时根据其他选择/数据加载动态组件。我发现angular.io的这份指南非常有用https://angular.io/guide/dynamic-component-loader

在一个类ComponentFactoryResolver https://angular.io/api/core/ComponentFactoryResolver

中,这是所有工作原理的魔力。

祝你好运!

答案 1 :(得分:0)

您可以使用本文:https://angular.io/guide/dynamic-component-loader

以下是将数据从API映射到Angular组件的方法:

在我的项目中,我正在使用类似将模板(API中的组件ID)映射到角度组件的方法,并且我有一个组件可以通过预先准备的地图将JSON数据解析为角度组件。

在获取包含页面数据的JSON(在我的情况下,它是模块数组)之后,我将该json放在一个使用* ngFor为组件创建容器的组件中:

<div *ngFor="let module of page.modules"
      [module]="module"
      module-controller>
</div>

在我的情况下,此模块由路由器提供。

模块控制器组件如下所述。

映射文件:

const componentMap = {
  123: RawHtmlComponent, // ID_FROM_API : ANGULAR_COMPONENT_CLASS
}

此配置是在模块控制器组件中处理的,该组件在上面用于将相关组件传递到其API ID(模板)。

ModuleControllerComponent通过配置创建动态组件,并具有模块输入以将数据从api传递到每个组件。

每个模块组件都应具有模块输入@Input() module: any;

ModuleControllerComponent:

@Component({
    selector: '[module-controller]',
    template: '<div class="module-controll" #moduleHandler></div>',
})
export class ModuleControllerComponent implements OnInit {

    @Input() module: any;

    @ViewChild('moduleHandler', {read: ViewContainerRef}) moduleHandler: any;

    constructor(private componentFactoryResolver: ComponentFactoryResolver) {
    }


    ngOnInit() {
        this.setController();
    }

    private setController() {
        const moduleComponent = componentMap[this.module.template];
        if ((this.module && this.module.template && moduleComponent)) {
            const factory = this.componentFactoryResolver.resolveComponentFactory(moduleComponent);
            this.createComponentFromModule(factory);
        }
    }

    private createComponentFromModule(factory) {
        const cmpRef: ComponentRef<any> = this.moduleHandler.createComponent(factory);
        cmpRef.instance.module = this.module; //passing api data to component
    }
}

请记住要在模块中的EntryComponents中添加动态创建的组件! :)

我使用的是非常简化的版本,但是想法是相同的。您可以将其扩展到包含模块的部分(现在我正在使用部分,这是完美的)。您需要创建另一个控制器-section-controller和用于部分的另一个映射文件:)

希望我能帮到我,对我的英语很抱歉:D

P.S。您应该使用模块名称以外的其他名称,将其与角度模块混淆:D