【问题标题】:clarity custom filter (angular) not working correctly清晰度自定义过滤器(角度)无法正常工作
【发布时间】: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


    【解决方案1】:

    为了方便需要帮助的人,您应该为您的问题创建一个在线演示 - 例如 plnkr.co

    【讨论】:

    • 将尝试在 stackblitz 上进行
    • 我尝试重现错误,但数据来自 Firestore,我遇到了很多问题。
    猜你喜欢
    • 2014-07-01
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    • 2019-12-21
    • 2016-12-11
    • 2018-03-17
    • 1970-01-01
    • 2020-07-27
    相关资源
    最近更新 更多