简体   繁体   中英

How to pass data to different templates using *ngFor and *ngIf Angular 4

I have an object like below

let obj = [{
    templateId: 1,
    name: "Template 1"
}, {
    templateId: 2,
    name: "Template 1"
}, {
    templateId: 3,
    name: "Template 1"
}];

In HTML Template, I'm trying to pass data to different templates based on the tempalteId like below

<div *ngFor="let tmpl of obj">
    <div *ngIf="tmpl.templateId == 1; else templateTwo; context: tmpl">
        {{ tmpl.name }}
    </div>
</div>
<ng-template #templateTwo let-data="data">
    <div *ngIf="data.templateId == 2; else templateThree; context: data">
        {{ data.name }}
    </div>
</ng-template>
<ng-template #templateThree let-data="data">
    <div *ngIf="data.templateId == 3">
        {{ data.name }}
    </div>
</ng-template>

In the above html template, based on the templateId I want to pass the data to that respective template, but I am unable to do that as it throwing error in the template code, what is the wrong I am doing here.

Please let me know the right way.

you can use *ngTemplateOutlet directive on a ng-container element to pass your context to your desired template without changing your html structure :

<div *ngFor="let tmpl of obj">

   <div *ngIf="tmpl.templateId == 1">
      {{ tmpl.name }}
   </div>

   <ng-container *ngTemplateOutlet="templateTwo; context: tmpl"></ng-container>
   <ng-container *ngTemplateOutlet="templateThree; context: tmpl"></ng-container>

</div>

<ng-template #templateTwo  let-id="templateId" let-name="name">
   <div *ngIf="id == 2">
        {{ name }}
   </div> 
</ng-template>

<ng-template #templateThree  let-id="templateId" let-name="name">
   <div *ngIf="id == 3">
        {{ name }}
   </div> 
</ng-template>

example code on stackblitz.com

you can also put your ng-templates directly inside div with ngFor and simply use the same input variable you declared in your ngFor statment like this:

  <div *ngFor="let tmpl of obj">

    <div *ngIf="tmpl.templateId == 1; else templateTwo">
        {{ tmpl.name }}
    </div>

    <ng-template #templateTwo >
      <div *ngIf="tmpl.templateId == 2; else templateThree; ">
          {{ tmpl.name }}
      </div>
    </ng-template>

    <ng-template #templateThree >
        <div *ngIf="tmpl.templateId == 3">
            {{ tmpl.name }}
        </div>
    </ng-template>

  </div>

If i correctly understand your question and if you don't want to use ng-template then you can code like this:

<div *ngFor="let tmpl of obj">

    <div *ngIf="tmpl.templateId == 1">
        ...
    </div>

    <div *ngIf="tmpl.templateId == 2">
        ...
    </div>

    <div *ngIf="tmpl.templateId == 3">
        ...
    </div>

  </div>

For those who might stumble on it in future, my suggestion would be to solve it by using ng-container with an expression (assigned to *ngTemplateOutlet= ) that resolves with the name of the ng-template to use for the current object of the array being iterated.

<ng-template #templateOne let-tmpl="tmp">
  <div>
    {{ tmpl.name }}
  </div>
</ng-template>

<ng-template #templateTwo let-data="tmp">
  <div>
    {{ data.name }}
  </div>
</ng-template>

<ng-template #templateThree let-data="tmp">
  <div>
    {{ data.name }}
  </div>
</ng-template>

<div *ngFor="let tmpl of obj">
  <ng-container *ngTemplateOutlet="tmpl.templateId == 1 ? templateOne :
    tmpl.templateId == 2 ? templateTwo : templateThree; context: {tmp: tmpl}"></ng-container>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM