Loading dynamic templates in one component with Angular 4

My requirement is to create a component with 2 or more html templates, where each html template has at least 20 controls and loads this particular template based on several conditions.

Note. I chose 3 different templates, because the controls change depending on the type of template, where as a single file, ts as inputs and logic for driving receive and store values ​​in the template, remain the same. So I decided to go with 3 templates and a ts file as a single component.

//sub.component.ts
@Component({
     selector: 'sub-component',
     template: `
               <div [ngSwitch]="templateType">
                    <ng-template *ngSwitchCase="'1'"> ${require('./sub1.component.html')} </template>
                    <ng-template *ngSwitchCase="'2'"> ${require('./sub2.component.html')} </template>
                    <ng-template *ngSwitchCase="'3'"> ${require('./sub3.component.html')} </template>
                    <ng-template ngSwitchDefault> ${require('./sub1.component.html')} </template>
</div>
    `
})

I tried the above alternative as it looks like a simple solution to achieve the behavior, but compilation failure is not possible. In AngularJS, we have ng-Include to populate any template, but it looks like ng-template does not support loading external html content.

Do not put this as duplicate, as many queries like this appear, but most of the solutions are outdated or not applicable for Angular 4. Please advise the alternative instead of attaching different links.

+4
source share
2 answers

I know this question is old, but hopefully it helps people who are trying similar things.

, , , - . HTML. ng-include - un-sanitized HTML. P.I.T.A, , , ...

, templateRefs, , , ref . . 3 4 , . , .

ref

import { Directive, TemplateRef, Input } from '@angular/core';

@Directive({
 selector: 'get-template',
})
export class GetTemplateDirective {
  @Input() name: string;
  constructor(public template: TemplateRef<any>) {  }
}

,

@Component({
  selector: 'sub-component-templates',
  template: `

<ng-template get-template [name]="tpl1">
  Put Whatever here, including other components if you please
</ng-template> 

<ng-template get-template [name]="tpl2">
  Different template here
</ng-template> 

 ... and so on and so on...
`
})
export class Templates { }

, ,

ng-, , .

, ..

<sub-component>
    <sub-component-templates></sub-component-templates>
</sub-component>

 import { Component, ViewChild, ContentChildren, QueryList } from '@angular/core';
import { GetTemplateDirective } from 'wherever';

@Component({
selector: 'sub-component',
template: `

<ng-content></ng-content>

 <div #templateRenderer></div>
`
})
export class SubComponent {

@ViewChild('templateRenderer',{read:ViewContainerRef}) anchor: ViewContainerRef;
@ContentChildren(GetTemplateDirective) templates: QueryList<GetTemplateDirective>;

ngAfterContentInit()  {

  ... at this stage, you will have access to all the included templates with that directive on them. You can perform your logic to choose which one you want. Once you have selected the proper one, you can embed it like so ... 
 let desiredTemplateName = 'whatever';

     for (let t of this.templates.toArray()) {
       if(t.name === desiredTemplateName) {
          this.anchor.createEmbeddedView(t.template);
          break;        
       } 
     }  
   }

}

, , . ngSwitchCase, . , , , , , 100 ( , ), - .

. , - https://plnkr.co/edit/fdP9Oc?p=info

...

, , . ref...

 import { Component, ViewChild, ContentChildren, QueryList, TemplateRef } from '@angular/core';

 template: TemplateRef<any>;

, .

Angular 2/4 ... waaaaaay . , , .

+5

, , , , . , , - .

, , , , " 1-10", , .

, component ngIf, , , .

, .

Questions:[{
    question:'blahblahblah',
    answers: [..array of answers..],
    template: 'a'
    },
    {
    question: 'yaddayaddayadda',
    answers: [],
    template: 'b'
    },
    {
    etc.
    }
    ]

-

@Component ({
    selector: 'question-component',
    templateUrl: './template.html'
})

export class QuestionComponent {

    @input() data: yourDataType;

    constructor() {} 

}

-

<div *ngIf="data.template === a">
    <!-- code for template with binding and everything -->
</div>

<div *ngIf="data.template === b">
    <!-- code -->
</div>

<!-- etc. etc. etc. -->

-

<div *ngFor = "question of Questions">
    <question-component [data]="question"></question-component>
</div>

, , , , - . , .

0

Source: https://habr.com/ru/post/1680379/


All Articles