如何显示数组的第一行,然后显示angular2中的后续行

时间:2016-12-19 16:53:04

标签: angular

是否可以在特定行上显示数组的第一行,然后在单独的位置(例如新表或卡)中显示数组的其余部分。

例如,我有以下数据:

public records = [{
   firstName: "Joe",
   lastName: "Smith",
   favBooks: [ "1984", "Animal Farm", "Lord of the Rings", "Where the Sidewalk Ends"]
},
{
   firstName: "Jane",
   lastName: "Jameson",
   favBooks: [ "Harry Potter", "Ender's Game", "Chronicles of Narnia"
},
{
   firstName: "Sam",
   lastName: "Baker",
   favBooks: "The Pelican Brief"
}]

我希望输出显示如下:

tr.even {
  background-color: #C9D4D9;
}
th#accordian-icon 
td[name="accordian-icon"]
{
  width: 15px;
}
th#person-name 
td[name="person-name"]
{
  width: 250px;
}
th#fav-book 
td[name="fav-book"]
{
  width: 250px;
}
<table>
  <thead>
  <tr>
    <th id="accordion-icon"></th>
    <th id="person-name">Name</th>
    <th id="fav-book">Favorite Book(s)</th>
  </tr>
  </thead>
  <tbody>
  <tr>
    <td name="accordion-icon">+</td>
    <td name="person-name">Joe Smith</td>
    <td name="fav-book">1984</td>
  </tr>
  <tr class="even">
    <td name="accordian-icon">-</td>
    <td name="person-name">Jane Jameson</td>
    <td name="fav-book">Harry Potter</td>
  </tr>
  <tr class="even">
    <td name="accordian-icon"></td>
    <td name="person-name"></td>
    <td name="fav-book">Ender's Game</td>
  </tr>
  <tr class="even">
    <td name="accordian-icon"></td>
    <td name="person-name"></td>
    <td name="fav-book">Chronicles of Narnia</td>
  </tr>
  <tr class="">
    <td name="accordian-icon"></td>
    <td name="person-name">Sam Baker</td>
    <td name="fav-book">The Pelican Brief</td>
  </tr>
  </tbody>
</table>

这是我到目前为止(其中accordionToggle是一个图标名称):

<table>
  <thead>
  <tr>
    <th id="accordion-icon"></th>
    <th id="person-name">Name</th>
    <th id="fav-book">Favorite Book(s)</th>
  </tr>
  </thead>
  <tbody *ngFor="let record of records; let even = even">
  <tr [ngClass]="{even: even}"
      (click)="onTabClick($event)">
    <td name="accordion-icon">
      <i class="material-icons">{{accordionToggle}}</i>
    </td>
    <td name="person-name">{{record.firstName}} {{record.lastName}}</td>
    <td name="fav-book">{{record.favBooks[0]}}</td>
  </tr>
  <template [ngIf]="showBooks">
  <tr *ngFor="let book of favBooks"
      [ngClass]="{even:even}">
    <td name="accordian-icon"></td>
    <td name="person-name"></td>
    <td name="fav-book">{{book}}</td>
  </tr>
  </template>
  </tbody>
</table>

我遇到的问题是:

  1. 显然,在第二组行中,我有两个绑定,但不起作用。如何让ngIf和ngFor一起工作? (如果我将ngIf放在一个包含tr的单独div中,HTML会将新的行集视为大表的第一个单元格中的不同表。)   一个。我使用模板元素修复了这个问题。
  2. 第一本书在第二行重复。
  3. 当我点击任何主要行(具有名称的行)时,所有行都会打开。我只希望我点击的行打开。我肯定会有更多的搜索,我会弄清楚如何通过点击的实际行,但如果有一个简单的答案,我不介意。
  4. 最后一行只有一本书,不需要扩展。我想让它无法点击,但我不知道该怎么做。

1 个答案:

答案 0 :(得分:1)

  1. 没错。您也可以将其打包在<ng-container *ngIf>而不是<template [ngIf]
  2. 使用像record.favBooks | slice: 1
  3. 这样的SlicePipe
  4. 您可以使用record.opened等属性,然后点击
  5. 进行切换
  6. 确保您的favBooks属性始终是一个数组(请参阅下面的ngOnInit或使用此处所述的ArrayifyPipe管道Does NgFor support Arrays containing one Object)。然后,您可以像record.favBooks.length > 1这样的条件在您的视图上执行所需的逻辑
  7. Plunker Example

    以下是代码:

    查看

    <table>
      <thead>
      <tr>
        <th id="accordion-icon"></th>
        <th id="person-name">Name</th>
        <th id="fav-book">Favorite Book(s)</th>
      </tr>
      </thead>
      <tbody *ngFor="let record of records; let even = even">
        <tr [ngClass]="{even: even, clickable: record.favBooks.length > 1}" (click)="record.favBooks.length > 1 ? record.opened = !record.opened : false">
          <td name="accordion-icon">
            <i [ngClass]="{'material-icons': record.favBooks.length > 1, opened: record.opened}"></i>
          </td>
          <td name="person-name">{{record.firstName}} {{record.lastName}}</td>
          <td name="fav-book">{{record.favBooks[0]}}</td>
        </tr>
        <template [ngIf]="record.opened && record.favBooks.length > 1">
          <tr *ngFor="let book of record.favBooks | slice: 1" [ngClass]="{even:even}">
            <td name="accordian-icon"></td>
            <td name="person-name"></td>
            <td name="fav-book">{{book}}</td>
          </tr>
        </template>
      </tbody>
    </table>
    

    <强>组件

    export class AppComponent {
      records = [{
        firstName: "Joe",
        lastName: "Smith",
        favBooks: ["1984", "Animal Farm", "Lord of the Rings", "Where the Sidewalk Ends"]
      },
      {
        firstName: "Jane",
        lastName: "Jameson",
        favBooks: ["Harry Potter", "Ender's Game", "Chronicles of Narnia"]
      },
      {
        firstName: "Sam",
        lastName: "Baker",
        favBooks: "The Pelican Brief"
      }]
    
      ngOnInit() {
        this.records.forEach((x: any) => {
          x.favBooks = Array.isArray(x.favBooks) ? x.favBooks : [x.favBooks];
        })
      }
    };