带有内部数组的Angular2 MatTable数据

Posted

技术标签:

【中文标题】带有内部数组的Angular2 MatTable数据【英文标题】:Angular2 MatTable data with inner array 【发布时间】:2019-01-30 23:56:41 【问题描述】:

这是我在 Stack Overflow 上的第一篇文章,所以我希望我能说清楚。

我正在尝试创建一个包含动态列的表,但我不明白如何将 matColumnDef 绑定到数组中的特定元素位置。由于我的原始代码更复杂且难以理解,因此我将发布一个包含问题本身的更简单的版本。

所以这里是 html 代码。我应该为“日期”中的内部数组(数字)中的每个元素创建一个列,(在这种情况下,有 2 个,但在我的原始应用程序中,数组是动态的,有时它有 2 个元素,有时它有 4 个等)

<mat-form-field>
  <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">

  <!-- Position Column -->
  <ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef> No. </th>
    <td mat-cell *matCellDef="let element"> element.position </td>
  </ng-container>

  <!-- Name Column -->
  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef> Name </th>
    <td mat-cell *matCellDef="let element"> element.name </td>
  </ng-container>

  <!-- Weight Column -->
  <ng-container matColumnDef="weight">
    <th mat-header-cell *matHeaderCellDef> Weight </th>
    <td mat-cell *matCellDef="let element"> element.weight </td>
  </ng-container>

  <!-- Symbol Column -->
  <ng-container matColumnDef="symbol">
    <th mat-header-cell *matHeaderCellDef> Symbol </th>
    <td mat-cell *matCellDef="let element"> element.symbol </td>
  </ng-container>

<div *ngFor="let number of date;let i=index;">
 <ng-container matColumnDef="i">
    <th mat-header-cell *matHeaderCellDef> Symbol </th>
    <td mat-cell *matCellDef="let element"> element.numere[i] </td>
  </ng-container>
</div>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

这是打字稿代码:

import Component from '@angular/core';
import MatTableDataSource from '@angular/material';

export interface PeriodicElement 
  name: string;
  position: number;
  weight: number;
  symbol: string;
  numere: Array<string>;




/**
 * @title Table with filtering
 */
@Component(
  selector: 'table-filtering-example',
  styleUrls: ['table-filtering-example.css'],
  templateUrl: 'table-filtering-example.html',
)
export class TableFilteringExample 
  date: PeriodicElement[] = [
  position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H', numere: ["alb","negru"],
  position: 2, name: 'Helium', weight: 4.0026, symbol: 'He',numere: ["alb","negru"],
  position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li',numere: ["galben","roz"],
  position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be',numere: ["alb","negru"],
  position: 5, name: 'Boron', weight: 10.811, symbol: 'B',numere: ["galben","roz"],
  position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C',numere: ["alb","negru"],
  position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N',numere: ["maro","roz"],
  position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O',numere: ["pink","bombon roz"],
  position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F',numere: ["alb","negru"],
  position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne',numere: ["alb","negru"],
];
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol','0','1'];
  dataSource = new MatTableDataSource(this.date);

  applyFilter(filterValue: string) 
    this.dataSource.filter = filterValue.trim().toLowerCase();
  

现在..我想出了一种将元素分配给列的方法,通过将它们的索引设置为 0,1,2,...,array.length,我可以将它们显示在实际表中,但是...

问题是,如果我想在表格上添加过滤器或在这些列上添加 mat-sort-header,它将不起作用。例如,排序需要具有与 matColumnDef 相同的“属性名称”(即:element.position matColumnDef='position')。但是在这种情况下,我没有数组中每个元素的属性名称(例如'numere [0]'、'numere [1]'等),只有数组属性名称本身也是如此一般将其应用于所有列并且不起作用。

因此,如果我想根据表中的第一个元素 ('numere[0]') 对表进行排序,我将无法做到,因为没有像 numere[x] 这样的属性名称。

任何想法我怎么能做到这一点?另外,我想坚持使用 Angular Material 库而不是更改其他选项,因为据说我会这样做。

【问题讨论】:

【参考方案1】:

由于没有提到任何解决方案。我会用我的试试。 所以我必须展示最初为 maxSelectedItems="3"

的演员、导演和类型
actors: (2) […, …] , 
directors: […] , 
genres: (2) […, …] 

<ng-container matColumnDef="actors">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> Actors </th>
    <td mat-cell *matCellDef="let row">  row.actors[0].name row.actors[1] !== undefined ? row.actors[1].name : ''  row.actors[2] !== undefined ? row.actors[2].name : ''</td>
</ng-container>

【讨论】:

【参考方案2】:

我会处理数组并将其展平,以便数组内没有嵌套数组。如果我能在没有黑客攻击的情况下逃脱,我会的。

关于排序,Material 有自己的排序模块,不要忘记将它导入到你的模块中。否则 Angular 将忽略 matSort mat-sort-header 之类的指令而不会出现任何错误消息。我曾经想知道为什么我的排序不起作用,我发现我忘记导入MatSortModule

Material doc 网站如果在本文发布时处于离线状态,我认为是为了让排序正常工作:

    导入MatSortModulematSort 添加到mat-tabletable 元素 将mat-sort-header 添加到您要启用排序的mat-header-cell 使用@ViewChild 在组件类中获取matSort 将上述内容分配给生命周期钩子ngAfterViewInit中的数据源

我希望以上内容有所帮助。

【讨论】:

重点是我不能改变对象中的变量。我从后端收到一组对象: "userId": "-45", "mail": "alex@whatever.com" "username": "alex", "state": "1", " userChoices": [] 我在我的表中得到了一个名称列、邮件列、状态列和用户每个选择的列(因为一个选择属于一个问题,一个问题有它的列)。 我在表格上进行了排序和过滤,它在第一列上完美运行,除了来自问题的那些。它对它们没有任何作用,它看不到它们,问题肯定出在 columnId 上,因为必须有一个像 firstchoice 这样的字段名称并在其上绑定列。 从后端收到数据后,可以将其复制并展平到一个新的数组中,然后将数据源的数据属性设置为展平后的数组。如果您在执行此操作时遇到困难并需要帮助,请解释。

以上是关于带有内部数组的Angular2 MatTable数据的主要内容,如果未能解决你的问题,请参考以下文章

MatSort 打破 MatTable 详细信息行动画

1000 行中的 Angular 6 MatTable 性能

Angular系列之MatTable小技巧

Angular2:如何在组件内部显示组件标签的内部 HTML?

Angular 2 在 ngOnInit 承诺中推送数组后不刷新视图

Angular 2 在 ngOnInit 承诺中推送数组后不刷新视图