recursive dynamic template compilation in angular2

2019-02-19 12:39发布

问题:

I've based some of my work on the same problem described in here:

dynamic template to compile dynamic Component with Angular 2.0

How can I use/create dynamic template to compile dynamic Component with Angular 2.0?

The working plunker described in the question above can be found here.

The problem occours if the dynamic-detail tries to create another dynamic view that uses dynamic-detail in the template. If i try to do that i get the following exception.:

'dynamic-detail' is not a known element: 1. If 'dynamic-detail' is an Angular component, then verify that it is part of this module.

This is easily reprocuded by changing the logic in the plunker to create a dynamic template that outputs "<dynamic-detail></dynamic-detail>".

In the file "app/dynamic/template.builder.ts" I've changed the following code:

      let editorName = useTextarea 
    ? "text-editor"
    : "string-editor";

To

      let editorName = useTextarea 
    ? "dynamic-detail"
    : "string-editor";

When that happens i run into the exception above. Apparently the compiler is not familiar with dynamic-detail when it is done recursively.

I've tried to add the DynamicDetail to imports in the different modules without any luck. Maybe that's not part of the solution.

回答1:

If your change "text-editor" to "dynamic-detail" then your template will look like:

<form>
  <dynamic-detail
     [propertyName]="'code'"
     [entity]="entity"
   ></dynamic-detail>
   <dynamic-detail
      [propertyName]="'description'"
      [entity]="entity"
   ></dynamic-detail>
</form>

DynamicDetail component doesn't have propertyName and entity properties. So you can add their.

detail.view.ts

export class DynamicDetail implements AfterViewInit, OnChanges, OnDestroy, OnInit
{ 
    @Input()  public propertyName: string;
    @Input()  public entity: any;

Second part of solution is add this component to RuntimeComponentModule:

type.builder.ts

protected createComponentModule (componentType: any) {
  @NgModule({
    imports: [ 
      PartsModule,
      DynamicModule.forRoot() // this line
    ],
    declarations: [
      componentType
    ],
  })
  class RuntimeComponentModule {}

  return RuntimeComponentModule;
}

After that it should work Plunker Example