我的垫子表工作正常,我的所有列都在排序,除了我的最后一列使用reduce来计算其他列的总和值。
我有点卡在这个问题上,尽管首先可能是归约方法在OnInit
生命周期之后发生,但是即使我在this.dataSource.data = this.data
中声明ngAfterViewInit
也不起作用。 / p>
我的HTML模板:
<div [ngClass]="{'hidden': !hasData()}">
<div class="subcollection-name">{{subCollection.name}}</div>
<div class="table-container">
<table
matSort
mat-table
class="items-table"
[dataSource]="dataSource"
>
<ng-container matColumnDef="coverUrl">
<th mat-header-cell *matHeaderCellDef></th>
<td mat-cell *matCellDef="let item">
<img class="item-image" src="{{item.displayImage}}" onError="this.src='assets/images/no-image-available.png';">
</td>
<td mat-footer-cell *matFooterCellDef>
{{ "collectionReportsSubcollectionTablesTotalRow" | translate }}
<td>
</ng-container>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ 'collectionRejectionReportRejectedItemTableHeaderId' | translate}}
</th>
<td mat-cell *matCellDef="let item">
<a target="_blank" routerLink="/item/{{item.id}}" class="item-id-link">ID-{{ item.id }}</a>
</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
<ng-container matColumnDef="name" sticky>
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ 'collectionRejectionReportRejectedItemTableHeaderName' | translate}}
</th>
<td mat-cell *matCellDef="let item">{{ item | displayItemName }}</td>
<td mat-footer-cell *matFooterCellDef></td>
</ng-container>
<ng-container *ngFor="let step of stepsName$ | async">
<ng-container matColumnDef="{{step}}">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{step}}
</th>
<td mat-cell *matCellDef="let item">{{ 'stepsReportAverageTimeSpentDaysUnit' | translate: { numberDays: getDataOfItemForStepName(item.id, step) } }}</td>
<td mat-footer-cell *matFooterCellDef>{{ 'stepsReportAverageTimeSpentDaysUnit' | translate: { numberDays: getTotalDataOfStep(step) } }}</td>
</ng-container>
</ng-container>
<ng-container matColumnDef="total" stickyEnd>
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ "collectionReportsSubcollectionTablesTotalCollumn" | translate }}
</th>
<td mat-cell *matCellDef="let item">{{ 'stepsReportAverageTimeSpentDaysUnit' | translate:{ numberDays: getTotalDataOfItem(item.id) } }}</td>
<td mat-footer-cell *matFooterCellDef>{{ 'stepsReportAverageTimeSpentDaysUnit' | translate:{ numberDays: getTotalDataOfAll() } }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columns; sticky: true"></tr>
<tr mat-row *matRowDef="let row; columns: columns;"></tr>
<tr mat-footer-row *matFooterRowDef="columns"></tr>
</table>
</div>
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]"></mat-paginator>
</div>
TypeScript文件
import { Observable, BehaviorSubject } from 'rxjs';
import { SubCollection } from 'model/item-tree/collection';
import { MatSort, MatPaginator, MatTableDataSource } from '@angular/material';
import { Component, ViewChild, Input, OnInit, ChangeDetectionStrategy, AfterViewInit, OnChanges } from '@angular/core';
@Component({
selector: 'app-collection-steps-report-subcollection-table',
templateUrl: './collection-steps-report-subcollection-table.component.html',
styleUrls: ['./collection-steps-report-subcollection-table.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class CollectionStepsReportSubcollectionTableComponent implements OnInit {
@ViewChild(MatSort, { static: true }) sort: MatSort;
@ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
@Input() data: any[];
@Input() subCollection: SubCollection;
@Input() filterBy$: Observable<string>;
@Input() stepsName$: BehaviorSubject<string[]>;
public columns: string[];
public dataSource = new MatTableDataSource();
public ngOnInit(): void {
this.dataSource.filterPredicate = (data: any, filter: string): boolean => {
if (filter === 'id') {
return true;
}
const id = data['id'] as string;
const name = data['name'] as string;
const matchId = (id) ? id.trim().toLowerCase().indexOf(filter) !== -1 : true;
const matchName = (name) ? name.trim().toLowerCase().indexOf(filter) !== -1 : true;
return matchName || matchId;
};
this.dataSource.sort = this.sort;
this.dataSource.paginator = this.paginator;
this.filterBy$.subscribe(
filter => {
this.dataSource.filter = filter.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
);
this.stepsName$.subscribe(
sn => {
this.columns = ['coverUrl', 'id', 'name', ...sn, 'total'];
}
);
this.dataSource.data = this.data;
}
public hasData(): boolean {
return Array.isArray(this.data) && this.data.length > 0;
}
public getTotalDataOfItem(itemId: string): number {
const item = this.data.find(i => i.id === itemId);
return this.stepsName$.getValue().reduce((acc, stepName) => {
return acc += item[stepName];
}, 0);
}
public getTotalDataOfAll(): number {
return this.data.reduce(
(acc1, item) => acc1 += this.stepsName$.getValue().reduce((acc2, stepName) => acc2 += item[stepName], 0)
, 0);
}
public getDataOfItemForStepName(itemId: string, stepName: string): string {
return this.data.find(i => i.id === itemId)[stepName];
}
public getTotalDataOfStep(step: string): number {
return this.data.reduce((acc, item) => acc += item[step], 0);
}
}
很高兴有任何提示或帮助澄清我的想法来解决这个问题:)谢谢!
答案 0 :(得分:0)
经过一番尝试,我发现我的问题是'total'列不是'item'对象的一部分。
因此,我对数据实现了map
方法,将getTotalDataOfItem
函数的返回值分配给了ngOnInit
内的新数据数组,并且效果很好!
由于我的商品现在具有“总计”列,因此我必须重构HTML模板以在item.total
中呈现<td>
,而不是返回getTotalDataOfItem(item.id)
要使其正常工作,只需将此代码添加到TS文件的ngOnInit
内
const dataWithTotal = this.data.map(
value => {
return {
...value, total: this.getTotalDataOfItem(value['id'])
};
}
);
然后像这样重构HTML文件
<td mat-cell *matCellDef="let item">{{ 'stepsReportAverageTimeSpentDaysUnit' | translate:{ numberDays: item.total } }}</td>
然后享受您的mat-table正确排序所有列的方法:)