【问题标题】:How to show first row of an array and then the subsequent rows in angular2如何显示数组的第一行,然后显示 angular2 中的后续行
【发布时间】:2017-05-04 18:56:03
【问题描述】:

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

例如,我有以下数据:

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. 最后一行只有一本书,不需要展开。我想让它无法点击,但我不知道该怎么做。

【问题讨论】:

    标签: angular


    【解决方案1】:
    1. 没错。您也可以将其包装在 &lt;ng-container *ngIf&gt; 而不是 &lt;template [ngIf]
    2. record.favBooks | slice: 1一样使用SlicePipe
    3. 您可以使用record.opened 等属性并通过单击进行切换
    4. 确保您的favBooks 属性始终是一个数组(参见下面的ngOnInit 或使用ArrayifyPipe 管道,如此处所述Does NgFor support Arrays containing one Object)。然后你可以像record.favBooks.length &gt; 1这样的条件来在你的视图上做想要的逻辑

    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];
        })
      }
    };
    

    【讨论】:

    • 太好了,谢谢!甚至给了我一个 plunker 页面来玩这个例子。
    猜你喜欢
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 2015-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多