【发布时间】:2021-09-09 03:02:50
【问题描述】:
我有一个数据网格表,其中一列是“状态”。我正在尝试构建一个自定义过滤器,它会给我一个下拉菜单,并允许用户选择值。我还希望该列被预设为不包含数组中的两个值,“PAID”和“IN_PROCESS”。 一切都执行得很好;只有一个问题:数据仅被过滤为数组中的一个值“FAILED”。所有其他文档都不会显示。我不知道为什么。我是否将“FAILED”作为数组中的第一个值或之后的任何值都没有关系。 这是我的代码:
import {ChangeDetectionStrategy, Component, OnInit} from '@angular/core';
import {BehaviorSubject, combineLatest, Observable, Subject} from "rxjs";
import {AngularFirestore} from "@angular/fire/firestore";
import {
PaginatorNew,
PaybackScheduleState,
// ScheduleStatus,
Transaction
} from "../../transactions/transactions/Transaction.interface";
import {catchError, distinctUntilChanged, map, switchMap, tap} from "rxjs/operators";
import {ClrDatagridFilterInterface, ClrDatagridStateInterface} from "@clr/angular";
let STATE: PaybackScheduleState = {
transactions: [],
pagination: {
after: undefined,
before: undefined,
limit: 10,
},
filters: [],
};
@Component({
selector: 'app-payback-schedule',
templateUrl: './payback-schedule.component.html',
styleUrls: ['./payback-schedule.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PaybackScheduleComponent implements OnInit {
store = new BehaviorSubject(STATE);
public state$ = this.store.asObservable();
statusFilter: StatusFilter;
statusFilterValues = ['PAID', 'IN_PROCESS', 'FAILED', 'SCHEDULED', 'ERROR', 'CANCELLED']
pagination$ = this.state$.pipe(
map((state) => state.pagination),
distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),
);
filters$ = this.state$.pipe(
map((state) => state.filters),
distinctUntilChanged()
);
transactionsPayBackSchedules$: Observable<Transaction[]> = combineLatest([this.pagination$, this.filters$]).pipe(
switchMap(([pagination, filters]) => {
return this.afs
.collection<Transaction>('transactions', (ref) => {
let query: any = ref;
if (filters) {
for (const filter of filters) {
if (filter.property === 'paybackSchedule.status') {
const value = filter.value;
query = query.where('status', 'in', this.statusFilter.value)
}
}
}
if (pagination.after) {
query = query
.orderBy('paybackSchedule.date', 'desc')
.startAfter(pagination.after.paybackSchedule.date)
.limit(pagination.limit)
} else if (pagination.before) {
query = query
.orderBy('paybackSchedule.date', 'desc')
.endBefore(pagination.before.paybackSchedule.date)
.limitToLast(pagination.limit)
} else {
query = query.limit(pagination.limit)
query = query.orderBy('paybackSchedule.date', 'desc').limit(pagination.limit)
}
return query;
})
.valueChanges()
.pipe(tap(paybackScheduleArray => {
const transactions = paybackScheduleArray;
this.updateState({...STATE, transactions});
console.log('this one', transactions);
}))
}),
catchError(err => {
console.log(err);
return [];
})
)
constructor(public afs: AngularFirestore) {
}
nextPage(): void {
const state = this.store.getValue();
const pagination: PaginatorNew = {
after: state.transactions[state.transactions.length - 1],
before: undefined,
limit: state.pagination.limit,
};
this.updateState({...STATE, pagination});
}
previousPage(): void {
const state = this.store.getValue();
const pagination: PaginatorNew = {
before: state.transactions[0],
after: undefined,
limit: state.pagination.limit,
};
this.updateState({...STATE, pagination});
}
updatePageLimit(limit: number): void {
let pagination = this.store.getValue().pagination;
pagination = {...pagination, limit};
this.updateState({...STATE, pagination});
}
private updateState(state: PaybackScheduleState): void {
this.store.next((STATE = {...state}));
}
ngOnInit(): void {
this.statusFilter = new StatusFilter();
this.statusFilter.value = ['SCHEDULED','FAILED', 'CANCELLED', 'ERROR', ]
}
toggleSelection(event: any): void {
if (event.target.checked) {
this.statusFilter.value = event.target.value;
} else {
this.statusFilter.value = [''];
}
this.statusFilter.changes.next(true);
console.log(this.statusFilter.value);
}
onTableRefresh(state: ClrDatagridStateInterface<Transaction>): void {
console.log(state);
this.updateState({...STATE, filters: state.filters})
}
}
export class StatusFilter implements ClrDatagridFilterInterface<Transaction> {
changes = new Subject<any>();
value = [''];
property = 'paybackSchedule.status';
isActive(): boolean {
return this.value.length > 0;
}
accepts(transaction: Transaction) {
return true;
}
}
这是我的模板
<!--<div *ngIf="transactionsPayBackSchedules$ | async as transactionsPaybackSchedules">-->
<!-- <pre>{{transactionsPaybackSchedules | json}}</pre>-->
<!--</div>-->
<clr-datagrid (clrDgRefresh)="onTableRefresh($event)" *ngIf="transactionsPayBackSchedules$ | async as transactionsPaybackSchedules">
<clr-dg-placeholder>We couldn't find any transactions!</clr-dg-placeholder>
<clr-dg-column>
<ng-container *clrDgHideableColumn="{hidden: false}">
Date Requested
</ng-container>
</clr-dg-column>
<clr-dg-column>
<ng-container *clrDgHideableColumn="{hidden: false}">
Amount
</ng-container>
</clr-dg-column>
<clr-dg-column>
<ng-container *clrDgHideableColumn="{hidden: true}">
Schedule ID
</ng-container>
</clr-dg-column>
<clr-dg-column >
<ng-container *clrDgHideableColumn="{hidden: false}">
Status
<clr-dg-filter [clrDgFilter]="statusFilter" >
<clr-radio-wrapper *ngFor="let status of statusFilterValues">
<input
type="radio"
clrRadio
[value]="status"
name="status"
[checked]="statusFilter?.value?.includes(status)"
(change)="toggleSelection($event)">
/>
<label>{{status}}</label>
</clr-radio-wrapper>
</clr-dg-filter>
</ng-container>
</clr-dg-column>
<clr-dg-column>
<ng-container *clrDgHideableColumn="{hidden: false}">
Payback Date
</ng-container>
</clr-dg-column>
<clr-dg-row *ngFor="let paybackSchedule of transactionsPaybackSchedules">
<span
*ngIf="paybackSchedule?.paybackSchedule?.date?.seconds">{{paybackSchedule?.paybackSchedule?.date.seconds * 1000 }}</span>
<span
*ngIf="paybackSchedule?.paybackSchedule?.date && !paybackSchedule?.paybackSchedule?.date?.seconds">{{paybackSchedule?.paybackSchedule?.date}}</span>
<span *ngIf="paybackSchedule?.paybackSchedule?.date">{{paybackSchedule?.paybackSchedule?.date }}</span>
<clr-dg-cell *ngIf="paybackSchedule?.paybackSchedule?.date">{{paybackSchedule?.paybackSchedule?.date }}</clr-dg-cell>
<clr-dg-cell
*ngIf="paybackSchedule?.paybackSchedule?.amount">{{paybackSchedule?.paybackSchedule?.amount | currency}}</clr-dg-cell>
<clr-dg-cell *ngIf="paybackSchedule?.paybackSchedule?.scheduleId" >{{paybackSchedule?.paybackSchedule?.scheduleId}}</clr-dg-cell>
<clr-dg-cell>{{paybackSchedule?.paybackSchedule?.status || ""}}</clr-dg-cell>
<clr-dg-cell
*ngIf="paybackSchedule?.paybackSchedule?.paybackDate">{{paybackSchedule?.paybackSchedule?.paybackDate.toDate() | date:'short' }}</clr-dg-cell>
</clr-dg-row>
<clr-dg-footer>
<button (click)="previousPage()" class="btn btn btn-info btn-sm float-right">Prev</button>
<button (click)="nextPage()" class="btn btn btn-info btn-sm float-left">Next</button>
</clr-dg-footer>
</clr-datagrid>
这是我的界面
export interface PaybackSchedule {
amount: number;
paybackDate: Timestamp;
scheduleId: string;
status: ScheduleStatus[];
payrollValidated: boolean;
date: Timestamp;
cancellationReason: string;
caregiverId: string;
transactionId: string;
}
export enum ScheduleStatus {
ERROR = 'ERROR',
SCHEDULED = 'SCHEDULED',
IN_PROCESS = 'IN_PROCESS',
PAID = 'PAID',
CANCELLED = 'CANCELLED',
}
我尝试了很多不同的方法。想不通。
还有另一个问题:如果我确实使用了数组,然后尝试使用下拉菜单会出现错误,因为它是一个值而不是数组。
【问题讨论】:
标签: angular filter datagrid vmware-clarity