简体   繁体   中英

How to create template reference inside the `ngFor` loop with angular?

i am trying to create template reference through ngFor loop. but not works.

ts file:

import { Component, VERSION } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  members = [
    {
      name: 'name1',
      id:"one"
    },
    {
      name: 'name2',
      id:"two"
    },
    {
      name: 'name3',
      id:"three"
    } 
  ]
}

template:

<div class="container">
  <h2>Test popover</h2>
  <p>
    How to declare a dynamic template reference variable inside a ngFor element?
  </p>
</div>

<div *ngFor="let member of members">
  <ng-container [ngTemplateOutlet]="{{member.id}}"
    >Hello, <b>{{ member.name }}</b
    >!</ng-container
  >
</div>

<ng-template #one> one </ng-template>
<ng-template #two> two </ng-template>
<ng-template #three> three </ng-template>

Live demo

I am getting an error as:

Type '{ "": any; }' is not assignable to type 'TemplateRef<any>'. Object literal may only specify known properties, and '""' does not exist in type 'TemplateRef<any>'.

Update:

If you want to pass ngTemplate to child, you can use contentChild

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

@Component({
  selector: 'hello',
  template: `
  <div *ngFor="let member of members">
      {{member.name}} <ng-container [ngTemplateOutlet]="this[member.id]"></ng-container>
  </div>
  `,
  styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent {
  @ContentChild('one') one: TemplateRef<any>;
  @ContentChild('two') two: TemplateRef<any>;
  @ContentChild('three') three: TemplateRef<any>;
  @Input() members: any;
}

forked stackblitz

Solution1:

Instead of hardcoding the template names, you can just render based on the index

<div class="container">
  <h2>Test popover</h2>
  <p>
    How to declare a dynamic template reference variable inside a ngFor element?
  </p>
</div>
<div *ngFor="let member of members; let i = index">
  <ng-container *ngIf="temps">
    <ng-container [ngTemplateOutlet]="temps.toArray()[i]"
      >Hello, <b>{{ member.name }}</b
      >!</ng-container
    ></ng-container
  >
</div>

<ng-template #temp> one </ng-template>
<ng-template #temp> two </ng-template>
<ng-template #temp> three </ng-template>

forked stackblitz

Solution2:

You can chain ternary conditions so that you get the output as required

<div class="container">
  <h2>Test popover</h2>
  <p>
    How to declare a dynamic template reference variable inside a ngFor element?
  </p>
</div>

<div *ngFor="let member of members">
  <ng-container
    *ngTemplateOutlet="
      member.id === 'one' ? one : member.id === 'two' ? two : three
    "
    >Hello, <b>{{ member.name }}</b
    >!</ng-container
  >
</div>

<ng-template #one> one </ng-template>
<ng-template #two> two </ng-template>
<ng-template #three> three </ng-template>

forked stackblitz

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