Angular 6 - 在 Material 扩展面板内循环 Material Table
Angular 6 - Looping through Material Table inside Material Expansion Panel
我有一个问题有点迷茫。我有 material 扩展面板,其中 header 是通过循环包含我拥有的数据的变量来填充的,该变量是 objects 的数组 - 在 [=74= 的数组中】],有一个键值是扩展面板header。还有一个键,其值是 objects 的另一个数组,我想遍历其中以在每个扩展面板中填充一个 material table。
这是我目前所掌握的...
titleGroups.ts:
export const titles = [
{
title: 'First Title',
titleId: 'firstTitle',
info: [
{ name: 'Info One', code: 'infoOne' },
{ name: 'Info Two', code: 'infoTwo' },
{ name: 'Info Three', code: 'infoThree' },
{ name: 'Info Four', code: 'infoFour' }
]
},
{
title: 'Second Title',
titleId: 'secondTitle',
info: [
{ name: 'Package', code: 'package' },
{ name: 'Package Two', code: 'packageTwo' }
]
},
{
title: 'Third Title',
titleId: 'thirdTitle',
info: [
{ name: 'Widget One', code: 'widgetOne' },
{ name: 'Widget Two', code: 'widgetTwo' },
{ name: 'Widget Three', code: 'widgetThree' },
{ name: 'Widget Four', code: 'widgetFour' }
]
}
]
title.component.ts:
import {Component} from '@angular/core';
import {SelectionModel} from '@angular/cdk/collections';
import {MatTableDataSource} from '@angular/material';
import {titles} from './titleGroups';
export interface TitleNames {
name: string;
}
const TITLES: any[] = titles;
let TITLE_NAMES;
for(let i = 0; i < TITLES.length; i++)
for(let j = 0; j < TITLES[i].info.length; j++)
TITLE_NAMES = TITLES[i].info;
@Component({
selector: 'aa-titles',
templateUrl: './aa-titles.component.html',
styleUrls: ['./aa-titles.component.scss']
})
export class TitlesComponent {
displayedColumns: string[] = ['select', 'name'];
dataSource = new MatTableDataSource<TitleNames>(TITLE_NAMES);
selection = new SelectionModel<TitleNames>(true, []);
titleData: any;
constructor() {
this.titleData = TITLES;
}
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.data.length;
return numSelected === numRows;
}
masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.data.forEach(row => this.selection.select(row));
}
}
title.component.html:
<mat-accordion multi="true">
<mat-expansion-panel *ngFor="let item of titleData">
<mat-expansion-panel-header>{{item.title}}</mat-expansion-panel-header>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!-- Checkbox Column -->
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)">
</mat-checkbox>
</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>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"
(click)="selection.toggle(row)">
</tr>
</table>
</mat-expansion-panel>
</mat-accordion>
发生的事情是,在每个扩展面板下,它仅显示每个扩展面板下 titleGroups.ts 标题的最后一个元素的数据。
我要的是对应的扩展面板显示正确的数据
第一个显示 table 的标题扩展面板显示:
Info One
Info Two
Info Three
Info Four
第二个标题扩展面板显示 table 显示:
Package
Package Two
等等。我不知道如何做到这一点 - 任何帮助将不胜感激,谢谢!
您应该为每个 table 定义单独的 dataSource
-s 和 selectionModel
-s:
例如,您可以在 constructor
中定义这样的数组:
this.titlesForIterate = titles.map(item => {
// I'm not doing it here, but you can also deep clone the item object first
item.dataSource = new MatTableDataSource<WidgetNames>(item.info);
item.selectionModel = new SelectionModel<TitleNames>(true, []);
return item;
};
然后在扩展面板的 *ngFor
中使用 titlesForIterate
。
<mat-expansion-panel *ngFor="let item of titlesForIterate">
然后在每个扩展面板中使用它们自己的 dataSource
和 selectionModel
成员作为它们的 table。
<table mat-table [dataSource]="item.dataSource" class="mat-elevation-z8">
...
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="item.selection.hasValue() && isAllSelected(item)"
[indeterminate]="item.selection.hasValue() && !isAllSelected(item)">
</mat-checkbox>
...
注意:不要忘记重构isAllSelected
方法来接收父对象作为参数。
我有一个问题有点迷茫。我有 material 扩展面板,其中 header 是通过循环包含我拥有的数据的变量来填充的,该变量是 objects 的数组 - 在 [=74= 的数组中】],有一个键值是扩展面板header。还有一个键,其值是 objects 的另一个数组,我想遍历其中以在每个扩展面板中填充一个 material table。
这是我目前所掌握的...
titleGroups.ts:
export const titles = [
{
title: 'First Title',
titleId: 'firstTitle',
info: [
{ name: 'Info One', code: 'infoOne' },
{ name: 'Info Two', code: 'infoTwo' },
{ name: 'Info Three', code: 'infoThree' },
{ name: 'Info Four', code: 'infoFour' }
]
},
{
title: 'Second Title',
titleId: 'secondTitle',
info: [
{ name: 'Package', code: 'package' },
{ name: 'Package Two', code: 'packageTwo' }
]
},
{
title: 'Third Title',
titleId: 'thirdTitle',
info: [
{ name: 'Widget One', code: 'widgetOne' },
{ name: 'Widget Two', code: 'widgetTwo' },
{ name: 'Widget Three', code: 'widgetThree' },
{ name: 'Widget Four', code: 'widgetFour' }
]
}
]
title.component.ts:
import {Component} from '@angular/core';
import {SelectionModel} from '@angular/cdk/collections';
import {MatTableDataSource} from '@angular/material';
import {titles} from './titleGroups';
export interface TitleNames {
name: string;
}
const TITLES: any[] = titles;
let TITLE_NAMES;
for(let i = 0; i < TITLES.length; i++)
for(let j = 0; j < TITLES[i].info.length; j++)
TITLE_NAMES = TITLES[i].info;
@Component({
selector: 'aa-titles',
templateUrl: './aa-titles.component.html',
styleUrls: ['./aa-titles.component.scss']
})
export class TitlesComponent {
displayedColumns: string[] = ['select', 'name'];
dataSource = new MatTableDataSource<TitleNames>(TITLE_NAMES);
selection = new SelectionModel<TitleNames>(true, []);
titleData: any;
constructor() {
this.titleData = TITLES;
}
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.dataSource.data.length;
return numSelected === numRows;
}
masterToggle() {
this.isAllSelected() ?
this.selection.clear() :
this.dataSource.data.forEach(row => this.selection.select(row));
}
}
title.component.html:
<mat-accordion multi="true">
<mat-expansion-panel *ngFor="let item of titleData">
<mat-expansion-panel-header>{{item.title}}</mat-expansion-panel-header>
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
<!-- Checkbox Column -->
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="selection.hasValue() && isAllSelected()"
[indeterminate]="selection.hasValue() && !isAllSelected()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox (click)="$event.stopPropagation()"
(change)="$event ? selection.toggle(row) : null"
[checked]="selection.isSelected(row)">
</mat-checkbox>
</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>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"
(click)="selection.toggle(row)">
</tr>
</table>
</mat-expansion-panel>
</mat-accordion>
发生的事情是,在每个扩展面板下,它仅显示每个扩展面板下 titleGroups.ts 标题的最后一个元素的数据。
我要的是对应的扩展面板显示正确的数据
第一个显示 table 的标题扩展面板显示:
Info One
Info Two
Info Three
Info Four
第二个标题扩展面板显示 table 显示:
Package
Package Two
等等。我不知道如何做到这一点 - 任何帮助将不胜感激,谢谢!
您应该为每个 table 定义单独的 dataSource
-s 和 selectionModel
-s:
例如,您可以在 constructor
中定义这样的数组:
this.titlesForIterate = titles.map(item => {
// I'm not doing it here, but you can also deep clone the item object first
item.dataSource = new MatTableDataSource<WidgetNames>(item.info);
item.selectionModel = new SelectionModel<TitleNames>(true, []);
return item;
};
然后在扩展面板的 *ngFor
中使用 titlesForIterate
。
<mat-expansion-panel *ngFor="let item of titlesForIterate">
然后在每个扩展面板中使用它们自己的 dataSource
和 selectionModel
成员作为它们的 table。
<table mat-table [dataSource]="item.dataSource" class="mat-elevation-z8">
...
<mat-checkbox (change)="$event ? masterToggle() : null"
[checked]="item.selection.hasValue() && isAllSelected(item)"
[indeterminate]="item.selection.hasValue() && !isAllSelected(item)">
</mat-checkbox>
...
注意:不要忘记重构isAllSelected
方法来接收父对象作为参数。