Starfish
Starfish

Reputation: 3574

Create multiple elements in loop Angular2

Edit: About the possible answer: I came across that question/answer too and implemented it that way. However, with the new version of Angular2 the syntax is different. The documentation about ngFor wasn't updated (this is where I looked). So I wrote the wrong code. The documentation about ngFor is updated in the Template Syntax - ngFor. Günter wrote a correct example on how to use it in the newer versions of Angular2 (beta17 or higher).

I'd like to create multiple elements in a loop. This is what I have now:

<table>
    <thead>
        <th>ID</th>
        <th>Name</th>
    </thead>
    <tbody>
        <tr *ngFor="let item of items" class="info">
            <td>{{ item['id'] }}</td>
            <td>{{ item['name'] }}<td>
        </tr>
    </tbody>
</table>

What I'd like is under ever tr another tr with details. The desired output should look like this in the browser:

<table>
    <thead>
        <th>ID</th>
        <th>Name</th>
    </thead>
    <tbody>
        <tr class="info">
            <td>1</td>
            <td>Item 1<td>
        </tr>
        <tr class="details">
            <!-- More detailed info about item 1 -->
        </tr>
        <tr class="info">
            <td>2</td>
            <td>Item 2<td>
        </tr>
        <tr class="details">
            <!-- More detailed info about item 2 -->
        </tr>
    </tbody>
</table>

How can I achieve the desired result?

Upvotes: 5

Views: 6703

Answers (4)

Mate Šimović
Mate Šimović

Reputation: 945

Since Angular v4 <template> tag is deprecated. Use <ng-template> instead, as described in tutorial: ng-template-element

Upvotes: 1

gevorg
gevorg

Reputation: 5055

Use following component code:

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

@Component({
  selector: 'demo-app',
  templateUrl: 'app/app.component.html',
  pipes: []
})
export class AppComponent {
  constructor() { 
    this.items = [
        {id: 1, name: 'Bob', details: 'Bob details'},
        {id: 2, name: 'Sarah', details: 'Sarah details'},
        {id: 3, name: 'Sam', details: 'Sam details'},
        {id: 4, name: 'Susan', details: 'Susan details'}
    ];
  }
}

With following app.component.html file:

<table>
    <thead>
        <th>ID</th>
        <th>Name</th>
    </thead>
    <tbody>
      <template ngFor [ngForOf]="items" let-item>
        <tr class="info">
            <td>{{ item['id'] }}</td>
            <td>{{ item['name'] }}<td>
        </tr>
        <tr class="details">
            <td colspan=2>{{ item['details'] }}</td>
            <!-- More detailed info about item -->
        </tr>
      </template>
    </tbody>
</table>

Result is something like this:

<table>
    <thead>
        <th>ID</th>
        <th>Name</th>
    </thead>
    <tbody>
        <tr class="info">
            <td>1</td>
            <td>Bob</td><td>
        </td></tr>
        <tr class="details">
            <td colspan="2">Bob details</td>                
        </tr>          
        <tr class="info">
            <td>2</td>
            <td>Sarah</td><td>
        </td></tr>
        <tr class="details">
            <td colspan="2">Sarah details</td>                
        </tr>          
        <tr class="info">
            <td>3</td>
            <td>Sam</td><td>
        </td></tr>
        <tr class="details">
            <td colspan="2">Sam details</td>                
        </tr>          
        <tr class="info">
            <td>4</td>
            <td>Susan</td><td>
        </td></tr>
        <tr class="details">
            <td colspan="2">Susan details</td>                
        </tr>          
    </tbody>
</table>

For more information read https://coryrylan.com/blog/angular-2-ng-for-syntax

Upvotes: 2

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657058

<template ngFor [ngForOf]="items" let-item> is the canonical for of *ngFor and allows to repeat more than one element.

import {Component} from '@angular/core'

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <div>
      <h2>Hello {{name}}</h2>
<table>
    <thead>
        <th>ID</th>
        <th>Name</th>
    </thead>
    <tbody>
      <template ngFor [ngForOf]="items" let-item>
        <tr class="info">
          <td>{{ item['id'] }}</td>
          <td>{{ item['name'] }}<td>
        </tr>
        <tr class="details">
          <td>{{ item['description'] }}<td>
        </tr>
      </template>    
    </tbody>
</table>

    </div>
  `,
  directives: []
})
export class App {
  items = [
    {name: 'name1', id: 1, description: 'description1'}
    {name: 'name2', id: 2, description: 'description2'}
    {name: 'name3', id: 3, description: 'description3'}
  ];
  constructor() {
    this.name = 'Angular2 (Release Candidate!)'
  }
}

Plunker example

In contrary to Polymer (for example), using <template> within <tbody> (or other table elements <tr>, ...) also works fine in IE with Angular2, because Angular2 processes the template internally and never adds it to the DOM. In Polymer this would not work because IE removes "unexpected" tags from table elements (which breaks Poymers <template is="dom-repeat">) See also http://caniuse.com/#search=template

Upvotes: 9

Praveen Kumar P
Praveen Kumar P

Reputation: 86

You can achieve this by looping on <tbody> instead of <tr>, as tables with mutiple tbody is valid in html refer to.

So your code will be like

<table>
        <thead>
            <th>ID</th>
            <th>Name</th>
        </thead>
        <tbody *ngFor="let item of items; #idx = index">
            <tr class="info">
                <td>{{idx}}</td>
                <td>Item {{idx}}<td>
            </tr>
            <tr class="details">
                <td>{{ item['id'] }}</td>
                <td>{{ item['name'] }}<td>
            </tr>
         </tbody>
    </table>
</table>

Upvotes: 1

Related Questions