将行移到顶部 angular material table
Move Rows to top in angular material table
我创建了一个 mattable,它工作得很好。我通过将 JSON 属性 值与其他 JSON 值进行比较,将最后一列的值从 'No' 更改为 'Yes'。
到目前为止一切正常,但现在我想将这些行移动到顶部,其最后一列的值将更改为 'Yes'。
我在我的组件中获得了一个可观察对象,并且该可观察对象直接绑定到 mattable。业务逻辑在智能组件中实现,而哑组件仅显示数据。这是我的愚蠢组件代码。
<table mat-table [dataSource]="dataSource$" class="mat-elevation-z8">
<ng-container matColumnDef="srNo">
<th mat-header-cell *matHeaderCellDef> Sr No. </th>
<td mat-cell *matCellDef="let element;let i = index"> {{i + 1}} </td>
</ng-container>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef> Parcel ID </th>
<td mat-cell *matCellDef="let element"> {{element.id}} </td>
</ng-container>
<ng-container matColumnDef="zone">
<th mat-header-cell *matHeaderCellDef> Zone </th>
<td mat-cell *matCellDef="let element"> {{getZone(element)}} </td>
</ng-container>
<ng-container matColumnDef="zoneArea">
<th mat-header-cell *matHeaderCellDef> Zone Area </th>
<td mat-cell *matCellDef="let element"> {{getZoneArea(element)}} </td>
</ng-container>
<ng-container matColumnDef="customerAddress">
<th mat-header-cell *matHeaderCellDef> Customer Address </th>
<td mat-cell *matCellDef="let element"> {{element.customerData.address}} </td>
</ng-container>
<ng-container matColumnDef="vendor">
<th mat-header-cell *matHeaderCellDef> Vendor </th>
<td mat-cell *matCellDef="let element"> {{element.vendor.name}} </td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef> Scanned </th>
<td mat-cell *matCellDef="let element; let i = index">
<p class="text-bold" [ngClass]="{'green-fg': element.currentStatusId == statusRepo?.id,'red-fg' : element.currentStatusId !== statusRepo?.id}">
{{element.currentStatusId == statusRepo?.id ? 'YES' : 'NO'}}
</p>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
component.ts 文件
export class WarehouseParcelListComponent implements OnInit {
@Input() dataSource$: Observable<IParcel[]>;
@Input() statusRepo: IStatusRepository;
tableArray: IParcel[] = [];
data: MatTableDataSource<any>;
displayedColumns = [
'srNo',
'id',
'zone',
'zoneArea',
'customerAddress',
'vendor',
'status'
];
constructor() {}
ngOnInit() {}
getZone(parcel: IParcel) {
return parcel.zoneArea ? parcel.zoneArea.zone.name : null;
}
getZoneArea(parcel: IParcel) {
if (parcel.zoneArea) {
return parcel.zoneArea.name;
}
return parcel.zoneAreaId;
}
}
智能组件HTML文件
<div fxLayout="column" fxLayoutAlign="end end">
<app-parcel-id-input (submitId)="submitId($event)" *ngIf="(dataSource$ | async)?.length> 0" class="w-40-p">
</app-parcel-id-input>
</div>
<app-warehouse-parcel-list [statusRepo]="statusRepository" [dataSource$]="dataSource$"></app-warehouse-parcel-list>
智能组件ts文件
export class WarehouseParcelScanRiderComponent implements OnInit {
dataSource$: Observable<IParcel[]>;
statusRepository: IStatusRepository;
constructor(
private _ac: ActivatedRoute,
private _http: WarehouseScanParcelHttpService,
private _sb: SwyftSnackBarService,
private _localStorageService: LocalStorageService
) {
this._ac.params.subscribe(params => {
console.log(params);
if (params.pickupBatchId) {
this.fetchPickupBatch(params.pickupBatchId);
}
});
}
ngOnInit() {}
submitId(parcelId: string) {
this.dataSource$.pipe(take(1)).subscribe(data => {
if (data.filter(x => x.id === parcelId).length === 0) {
return this._sb.open({
message: 'Invalid parcel ID',
type: 'warning'
});
}
const filterParcels = () => {
return this.dataSource$.pipe(
flatMap(parcels =>
forkJoin([
of(parcels),
parcels.filter(p => p.id === parcelId)
])
)
);
};
const processData = (localStorageData: any) => {
return filterParcels().pipe(
flatMap(data => {
if (
data[1].currentStatusId === this.statusRepository.id
) {
this._sb.open({
message: 'This parcel is already scanned',
type: 'info'
});
return of(false);
}
return forkJoin([
of(data[0]),
this._http.createParcelStatus(
parcelId,
this.statusRepository.id,
localStorageData['userId']
)
]);
})
);
};
this._localStorageService
.getLocalStorageItem('pc_admin_data')
.pipe(
flatMap(processData),
take(1)
)
.subscribe(data => {
if (isBoolean(data)) {
return;
}
const index = data[0].findIndex(obj => obj.id === parcelId);
console.log(index);
const temp = [...data[0]];
console.log(temp);
temp[index].currentStatusId = this.statusRepository.id;
this.dataSource$ = of(temp);
console.log(temp);
console.log(this.dataSource$);
});
});
}
fetchPickupBatch(pickupBatchId: string) {
console.log('fetchinggg shitt');
const getParcelStatuses = (parcel: IParcel) => {
return this._http
.getParcelStatuses(parcel.id)
.pipe(map(data => ({ parcel, statuses: data })));
};
const transformParcels = (
parcels: IParcel[]
): Observable<IParcel[]> => {
const data = of(parcels).pipe(
mergeAll(),
mergeMap(getParcelStatuses),
toArray(),
map(_data =>
_data
.filter(obj => {
return obj.statuses.findIndex(
_obj =>
_obj.statusRepositoryId ===
this.statusRepository.id
) === -1
? true
: false;
})
.map(filteredData => filteredData.parcel)
)
);
return data;
};
const fetchCustomerData = (customerDataId: string) => {
return this._http.getCustomerData(customerDataId);
};
const fetchParcelZoneArea = (zoneAreaId: string) => {
return this._http.getZoneArea(zoneAreaId);
};
const fetchParcelZoneAreaAndCustomerAddress = (parcel: IParcel) => {
if (
parcel.zoneAreaId === 'INVALID_CUSTOMER_ADDRESS' ||
parcel.zoneAreaId === 'ZONE_NOT_DEFINED'
) {
return forkJoin([
fetchCustomerData(parcel.customerDataId),
of(null)
]);
}
return forkJoin([
fetchCustomerData(parcel.customerDataId),
fetchParcelZoneArea(parcel.zoneAreaId)
]);
};
const appendZoneDataAndCustomer = (parcel: IParcel) => {
return fetchParcelZoneAreaAndCustomerAddress(parcel).pipe(
map(data => {
const mappedParcel = parcel;
if (data[1]) {
mappedParcel.zoneArea = data[1];
}
mappedParcel.customerData = data[0];
return mappedParcel;
})
);
};
const fetchParcelVendor = (parcel: IParcel) => {
return this._http.getVendorById(parcel.vendorId).pipe(
map(vendor => {
const mappedParcel = parcel;
mappedParcel.vendor = vendor;
return mappedParcel;
})
);
};
this._http.getStatusRepository().subscribe(repo => {
this.statusRepository = repo;
this.dataSource$ = this._http
.getPickupBatchById(pickupBatchId)
.pipe(
mergeMap(pickupBatch => of(pickupBatch.parcelBatchIds)),
mergeAll(),
mergeMap(parcelBatchId =>
this._http.getBatchParcels(parcelBatchId)
),
toArray(),
mergeMap(dArray => of(dArray.flat())),
mergeMap(transformParcels),
mergeAll(),
mergeMap(appendZoneDataAndCustomer),
mergeMap(fetchParcelVendor),
toArray(),
tap(parcels => {
if (parcels.length === 0) {
this._sb.open({
message: 'No parcels found to scan',
type: 'info'
});
}
})
) as Observable<IParcel[]>;
});
}
}
你可以试试这个。
我认为你可以使用默认排序的 matSort table
在component.html文件中
<table mat-table [dataSource]="dataSource$" matSort class="mat-elevation-z8" matSortActive="name" matSortDirection="asc" matSortDisableClear>
....
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Scanned </th>
<td mat-cell *matCellDef="let element; let i = index">
<p class="text-bold" [ngClass]="{'green-fg': element.currentStatusId == statusRepo?.id,'red-fg' : element.currentStatusId !== statusRepo?.id}">
{{element.currentStatusId == statusRepo?.id ? 'YES' : 'NO'}}
</p>
</td>
</ng-container>
component.ts 文件
import {Component, OnInit, ViewChild} from '@angular/core';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource} from '@angular/material/table';
export class WarehouseParcelListComponent implements OnInit {
@Input() dataSource$: Observable<IParcel[]>;
@Input() statusRepo: IStatusRepository;
@ViewChild(MatSort, {static: true}) sort: MatSort;
tableArray: IParcel[] = [];
data: MatTableDataSource<any>;
displayedColumns = [
'srNo',
'id',
'zone',
'zoneArea',
'customerAddress',
'vendor',
'status'
];
constructor() {}
ngOnInit() {
this.dataSource$.sort = this.sort;
}
getZone(parcel: IParcel) {
return parcel.zoneArea ? parcel.zoneArea.zone.name : null;
}
getZoneArea(parcel: IParcel) {
if (parcel.zoneArea) {
return parcel.zoneArea.name;
}
return parcel.zoneAreaId;
}
}
我创建了一个 mattable,它工作得很好。我通过将 JSON 属性 值与其他 JSON 值进行比较,将最后一列的值从 'No' 更改为 'Yes'。
到目前为止一切正常,但现在我想将这些行移动到顶部,其最后一列的值将更改为 'Yes'。
我在我的组件中获得了一个可观察对象,并且该可观察对象直接绑定到 mattable。业务逻辑在智能组件中实现,而哑组件仅显示数据。这是我的愚蠢组件代码。
<table mat-table [dataSource]="dataSource$" class="mat-elevation-z8">
<ng-container matColumnDef="srNo">
<th mat-header-cell *matHeaderCellDef> Sr No. </th>
<td mat-cell *matCellDef="let element;let i = index"> {{i + 1}} </td>
</ng-container>
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef> Parcel ID </th>
<td mat-cell *matCellDef="let element"> {{element.id}} </td>
</ng-container>
<ng-container matColumnDef="zone">
<th mat-header-cell *matHeaderCellDef> Zone </th>
<td mat-cell *matCellDef="let element"> {{getZone(element)}} </td>
</ng-container>
<ng-container matColumnDef="zoneArea">
<th mat-header-cell *matHeaderCellDef> Zone Area </th>
<td mat-cell *matCellDef="let element"> {{getZoneArea(element)}} </td>
</ng-container>
<ng-container matColumnDef="customerAddress">
<th mat-header-cell *matHeaderCellDef> Customer Address </th>
<td mat-cell *matCellDef="let element"> {{element.customerData.address}} </td>
</ng-container>
<ng-container matColumnDef="vendor">
<th mat-header-cell *matHeaderCellDef> Vendor </th>
<td mat-cell *matCellDef="let element"> {{element.vendor.name}} </td>
</ng-container>
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef> Scanned </th>
<td mat-cell *matCellDef="let element; let i = index">
<p class="text-bold" [ngClass]="{'green-fg': element.currentStatusId == statusRepo?.id,'red-fg' : element.currentStatusId !== statusRepo?.id}">
{{element.currentStatusId == statusRepo?.id ? 'YES' : 'NO'}}
</p>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
component.ts 文件
export class WarehouseParcelListComponent implements OnInit {
@Input() dataSource$: Observable<IParcel[]>;
@Input() statusRepo: IStatusRepository;
tableArray: IParcel[] = [];
data: MatTableDataSource<any>;
displayedColumns = [
'srNo',
'id',
'zone',
'zoneArea',
'customerAddress',
'vendor',
'status'
];
constructor() {}
ngOnInit() {}
getZone(parcel: IParcel) {
return parcel.zoneArea ? parcel.zoneArea.zone.name : null;
}
getZoneArea(parcel: IParcel) {
if (parcel.zoneArea) {
return parcel.zoneArea.name;
}
return parcel.zoneAreaId;
}
}
智能组件HTML文件
<div fxLayout="column" fxLayoutAlign="end end">
<app-parcel-id-input (submitId)="submitId($event)" *ngIf="(dataSource$ | async)?.length> 0" class="w-40-p">
</app-parcel-id-input>
</div>
<app-warehouse-parcel-list [statusRepo]="statusRepository" [dataSource$]="dataSource$"></app-warehouse-parcel-list>
智能组件ts文件
export class WarehouseParcelScanRiderComponent implements OnInit {
dataSource$: Observable<IParcel[]>;
statusRepository: IStatusRepository;
constructor(
private _ac: ActivatedRoute,
private _http: WarehouseScanParcelHttpService,
private _sb: SwyftSnackBarService,
private _localStorageService: LocalStorageService
) {
this._ac.params.subscribe(params => {
console.log(params);
if (params.pickupBatchId) {
this.fetchPickupBatch(params.pickupBatchId);
}
});
}
ngOnInit() {}
submitId(parcelId: string) {
this.dataSource$.pipe(take(1)).subscribe(data => {
if (data.filter(x => x.id === parcelId).length === 0) {
return this._sb.open({
message: 'Invalid parcel ID',
type: 'warning'
});
}
const filterParcels = () => {
return this.dataSource$.pipe(
flatMap(parcels =>
forkJoin([
of(parcels),
parcels.filter(p => p.id === parcelId)
])
)
);
};
const processData = (localStorageData: any) => {
return filterParcels().pipe(
flatMap(data => {
if (
data[1].currentStatusId === this.statusRepository.id
) {
this._sb.open({
message: 'This parcel is already scanned',
type: 'info'
});
return of(false);
}
return forkJoin([
of(data[0]),
this._http.createParcelStatus(
parcelId,
this.statusRepository.id,
localStorageData['userId']
)
]);
})
);
};
this._localStorageService
.getLocalStorageItem('pc_admin_data')
.pipe(
flatMap(processData),
take(1)
)
.subscribe(data => {
if (isBoolean(data)) {
return;
}
const index = data[0].findIndex(obj => obj.id === parcelId);
console.log(index);
const temp = [...data[0]];
console.log(temp);
temp[index].currentStatusId = this.statusRepository.id;
this.dataSource$ = of(temp);
console.log(temp);
console.log(this.dataSource$);
});
});
}
fetchPickupBatch(pickupBatchId: string) {
console.log('fetchinggg shitt');
const getParcelStatuses = (parcel: IParcel) => {
return this._http
.getParcelStatuses(parcel.id)
.pipe(map(data => ({ parcel, statuses: data })));
};
const transformParcels = (
parcels: IParcel[]
): Observable<IParcel[]> => {
const data = of(parcels).pipe(
mergeAll(),
mergeMap(getParcelStatuses),
toArray(),
map(_data =>
_data
.filter(obj => {
return obj.statuses.findIndex(
_obj =>
_obj.statusRepositoryId ===
this.statusRepository.id
) === -1
? true
: false;
})
.map(filteredData => filteredData.parcel)
)
);
return data;
};
const fetchCustomerData = (customerDataId: string) => {
return this._http.getCustomerData(customerDataId);
};
const fetchParcelZoneArea = (zoneAreaId: string) => {
return this._http.getZoneArea(zoneAreaId);
};
const fetchParcelZoneAreaAndCustomerAddress = (parcel: IParcel) => {
if (
parcel.zoneAreaId === 'INVALID_CUSTOMER_ADDRESS' ||
parcel.zoneAreaId === 'ZONE_NOT_DEFINED'
) {
return forkJoin([
fetchCustomerData(parcel.customerDataId),
of(null)
]);
}
return forkJoin([
fetchCustomerData(parcel.customerDataId),
fetchParcelZoneArea(parcel.zoneAreaId)
]);
};
const appendZoneDataAndCustomer = (parcel: IParcel) => {
return fetchParcelZoneAreaAndCustomerAddress(parcel).pipe(
map(data => {
const mappedParcel = parcel;
if (data[1]) {
mappedParcel.zoneArea = data[1];
}
mappedParcel.customerData = data[0];
return mappedParcel;
})
);
};
const fetchParcelVendor = (parcel: IParcel) => {
return this._http.getVendorById(parcel.vendorId).pipe(
map(vendor => {
const mappedParcel = parcel;
mappedParcel.vendor = vendor;
return mappedParcel;
})
);
};
this._http.getStatusRepository().subscribe(repo => {
this.statusRepository = repo;
this.dataSource$ = this._http
.getPickupBatchById(pickupBatchId)
.pipe(
mergeMap(pickupBatch => of(pickupBatch.parcelBatchIds)),
mergeAll(),
mergeMap(parcelBatchId =>
this._http.getBatchParcels(parcelBatchId)
),
toArray(),
mergeMap(dArray => of(dArray.flat())),
mergeMap(transformParcels),
mergeAll(),
mergeMap(appendZoneDataAndCustomer),
mergeMap(fetchParcelVendor),
toArray(),
tap(parcels => {
if (parcels.length === 0) {
this._sb.open({
message: 'No parcels found to scan',
type: 'info'
});
}
})
) as Observable<IParcel[]>;
});
}
}
你可以试试这个。
我认为你可以使用默认排序的 matSort table
在component.html文件中
<table mat-table [dataSource]="dataSource$" matSort class="mat-elevation-z8" matSortActive="name" matSortDirection="asc" matSortDisableClear>
....
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Scanned </th>
<td mat-cell *matCellDef="let element; let i = index">
<p class="text-bold" [ngClass]="{'green-fg': element.currentStatusId == statusRepo?.id,'red-fg' : element.currentStatusId !== statusRepo?.id}">
{{element.currentStatusId == statusRepo?.id ? 'YES' : 'NO'}}
</p>
</td>
</ng-container>
component.ts 文件
import {Component, OnInit, ViewChild} from '@angular/core';
import {MatSort} from '@angular/material/sort';
import {MatTableDataSource} from '@angular/material/table';
export class WarehouseParcelListComponent implements OnInit {
@Input() dataSource$: Observable<IParcel[]>;
@Input() statusRepo: IStatusRepository;
@ViewChild(MatSort, {static: true}) sort: MatSort;
tableArray: IParcel[] = [];
data: MatTableDataSource<any>;
displayedColumns = [
'srNo',
'id',
'zone',
'zoneArea',
'customerAddress',
'vendor',
'status'
];
constructor() {}
ngOnInit() {
this.dataSource$.sort = this.sort;
}
getZone(parcel: IParcel) {
return parcel.zoneArea ? parcel.zoneArea.zone.name : null;
}
getZoneArea(parcel: IParcel) {
if (parcel.zoneArea) {
return parcel.zoneArea.name;
}
return parcel.zoneAreaId;
}
}