使用json模式加载Angular 4动态组件

时间:2017-10-14 18:46:32

标签: json angular components on-the-fly

我正在创建一个小poc,以尝试是否可以根据给定的json数据结构加载组件。 json将提供组件选择器和数组。我根据在网上找到的参考资料尝试了一个小例子。我使用了Angular

推荐的“componentFactoryResolver”

我基本上创建了几个组件并使用entrycomponent装饰器注册它,如我的模块

中所示
entryComponents: [PersonalDetailsComponent, ContactDetailsComponent],

在我的应用程序组件中,我使用以下代码

  @ViewChild('dynamicInsert', { read: ViewContainerRef }) dynamicInsert: ViewContainerRef;
  constructor(private componentFactoryResolver: ComponentFactoryResolver) {
  }
  ngAfterViewInit() {
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(PersonalDetailsComponent );
    const componentFactory2 = this.componentFactoryResolver.resolveComponentFactory(ContactDetailsComponent);
    this.dynamicInsert.clear();
    this.dynamicInsert.createComponent(componentFactory);
    this.dynamicInsert.createComponent(componentFactory2);
  }

正如您所见,我必须为我使用的每个组件创建组件。但是这个内部循环可能不是最好的方法。如果有人能够以适当的方式做一些事情,我将非常感激。 我的实际json看起来像这样

{
         "step":"1",
         "viewed":false,
         "stepDependant":{
            "parentComponent":null,
            "childComponent":null,
            "varMap":null
         },
         "widgets":[
            {
               "Component":"shipper",
               "inputs":[
                  {
                     "ServiceLine":"Export"
                  }
               ],
               "outputs":[

               ],
               "name":"Shipper Details"
            },
            {
               "Component":"shipper",
               "inputs":[
                  {
                     "ServiceLine":"Export"
                  }
               ],
               "outputs":[

               ],
               "name":"Consignee Details"
            },
            {
               "Component":"status-of-shipment",
               "inputs":[

               ],
               "outputs":[

               ],
               "name":"Status of Shipment"
            }
         ]
      }

非常感谢您的投入

1 个答案:

答案 0 :(得分:2)

您已经发现componentFactoryResolver是从代码动态创建组件的正确方法。 使用这种方法,我将在您的情况下创建一个映射或服务,将组件选择器映射到组件类型。这样,您可以在从JSON数据创建动态组件时快速查找类型。然后从类型中解析工厂,然后添加样品中的组件。

如果您有一组已知的预定义组件,则另一种方法是在父组件中将它们全部定义为<ng-template>,如下所示:

<ng-template #shipper><shipper ></shipper></ng-template>
<ng-template #statusOfShippment><status-of-shipment ></status-of-shipment></ng-template>

然后,您可以使用@ViewChild装饰器获取组件中的模板。

@ViewChild('shipper')
shipperTemplate: TemplateRef<any>;
@ViewChild('statusOfShippment')
statusOfShippmentTemplate: TemplateRef<any>;

然后你可以用比工厂更简单的方式创建组件。

this.dynamicInsert.createEmbeddedView(shipper);
this.dynamicInsert.createEmbeddedView(statusOfShippment);

这种方法的好处在于您仍然可以使用经典模板绑定并向每个模板发送不同的上下文对象。

<ng-template #shipper><shipper [ServiceLine]="ServiceLine"></shipper></ng-template>

this.dynamicInsert.createEmbeddedView(shipper, {ServiceLine:"Export"});

这样您就可以直接发送从JSON创建的对象并配置组件绑定。如果使用组件工厂,则需要手动设置代码中的所有内容。