Search code examples
angulartypescriptcompilationangular2-compiler

recursive dynamic template compilation in angular2


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.


Solution

  • 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