Angular Paginator после фильтрации

Я хочу реализовать в своем проекте сортировку, разбиение по страницам и фильтрацию. Когда я иду фильтровать данные в таблице, мне показывается только соответствие данных, присутствующих на текущей странице. Допустим, на первой странице есть только 5 данных. , фильтр работает только на них. Это не работает на всей странице.

Вот коды

ТС:

export class ListComponent extends BaseComponent implements OnInit {
  constructor(spinner: NgxSpinnerService,
    private productService: ProductService,
    private alertifyService: AlertifyService,
    private dialogService: DialogService) {
    super(spinner)
  }


  displayedColumns: string[] = ['name', 'stock', 'price', 'createdDate', 'updatedDate', 'photos', 'qrcode', 'edit', 'delete'];
  dataSource: MatTableDataSource<List_Product> = null;
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;

  async getProducts() {
    this.showSpinner(SpinnerType.BallAtom);
    const allProducts: { totalProductCount: number; products: List_Product[] } = await this.productService.read(this.paginator ? this.paginator.pageIndex : 0, this.paginator ? this.paginator.pageSize : 5, () => this.hideSpinner(SpinnerType.BallAtom), errorMessage => this.alertifyService.message(errorMessage, {
      dismissOthers: true,
      messageType: MessageType.Error,
      position: Position.TopRight
    }))
    this.dataSource = new MatTableDataSource<List_Product>(allProducts.products);
    this.paginator.length = allProducts.totalProductCount;
  }

  addProductImages(id: string) {
    this.dialogService.openDialog({
      componentType: SelectProductImageDialogComponent,
      data: id,
      options: {
        width: "1400px"
      }
    });
  }

  async pageChanged() {
    await this.getProducts();
  }

  async ngOnInit() {
    await this.getProducts();
  }

  showQRCode(productId: string) {
    this.dialogService.openDialog({
      componentType: QrcodeDialogComponent,
      data: productId,
      afterClosed: () => { }
    })
  }

  ngAfterViewInit() {
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }


  filter(filterValue: string) {
    filterValue = filterValue.trim();
    filterValue = filterValue.toLowerCase();
    this.dataSource.filter = filterValue;
  }

}

HTML

<div class = "example-header">
  <mat-form-field>
    <input matInput (keyup) = "filter($any($event.target).value)" placeholder = "Filter">
  </mat-form-field>
</div>
<div class = " mat-elevation-z8">
  <table mat-table [dataSource] = "dataSource" matSort>

    <ng-container matColumnDef = "name">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
      <td mat-cell *matCellDef = "let element"> {{element.name}} </td>
    </ng-container>

    <ng-container matColumnDef = "stock">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Stock </th>
      <td mat-cell *matCellDef = "let element"> {{element.stock}} </td>
    </ng-container>

    <ng-container matColumnDef = "price">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Price </th>
      <td mat-cell *matCellDef = "let element"> {{element.price}}$ </td>
    </ng-container>

    <ng-container matColumnDef = "createdDate">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Created Date </th>
      <td mat-cell *matCellDef = "let element"> {{element.createdDate}} </td>
    </ng-container>

    <ng-container matColumnDef = "updatedDate">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Updated Date </th>
      <td mat-cell *matCellDef = "let element"> {{element.updatedDate}} </td>
    </ng-container>

    <ng-container matColumnDef = "photos">
      <th mat-header-cell *matHeaderCellDef width = "30">  </th>
      <td mat-cell *matCellDef = "let element"> <img style = "cursor:pointer" (click) = "addProductImages(element.id)" src = "../../../../../assets/add_a_photo_24dp_5F6368_FILL0_wght400_GRAD0_opsz24.png" width = "25" height = "25" /> </td>
    </ng-container>

    <ng-container matColumnDef = "qrcode">
      <th mat-header-cell *matHeaderCellDef width = "30">  </th>
      <td mat-cell *matCellDef = "let element"> <img style = "cursor:pointer" src = "../../../../../assets/qrcode.png" width = "25" height = "25" (click) = "showQRCode(element.id)" /> </td>
    </ng-container>

    <ng-container matColumnDef = "edit">
      <th mat-header-cell *matHeaderCellDef width = "30">  </th>
      <td mat-cell *matCellDef = "let element"> <img style = "cursor:pointer;" src = "../../../../../assets/update_24dp_5F6368_FILL0_wght400_GRAD0_opsz24.png" width = "25" height = "25" /> </td>
    </ng-container>

    <ng-container matColumnDef = "delete">
      <th mat-header-cell *matHeaderCellDef width = "30">  </th>
      <td mat-cell *matCellDef = "let element"
          appDelete
          [id] = "element.id"
          (callback) = "getProducts()"
          controller = "products">
      </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef = "displayedColumns"></tr>
    <tr mat-row *matRowDef = "let row; columns: displayedColumns;"></tr>

  </table>

  <mat-paginator (page) = "pageChanged()"
                 [pageSizeOptions] = "[5, 10, 20, 50, 100]"
                 showFirstLastButtons
                 aria-label = "Select page of periodic elements">
  </mat-paginator>
</div>
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
1
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы неправильно применяете фильтрацию. Вам необходимо отправить информацию о фильтрации на серверную часть в качестве параметра запроса. Затем отфильтруйте данные на бэкэнде и верните первую страницу и т. д.

Я бы порекомендовал вам выполнить вышеуказанные изменения, если в этом нет необходимости, воспользуйтесь описанным ниже подходом.


В настоящее время проблема с вашим кодом заключается в том, что вы сбрасываете отфильтровать через строку ниже:

this.dataSource = new MatTableDataSource<List_Product>(allProducts.products);

Мы можем повторно применить фильтр после воссоздания источника данных. Мы создаем клон, используя StructuredClone:

async getProducts() {
    this.showSpinner(SpinnerType.BallAtom);
    const allProducts: { totalProductCount: number; products: List_Product[] } = await this.productService.read(this.paginator ? this.paginator.pageIndex : 0, this.paginator ? this.paginator.pageSize : 5, () => this.hideSpinner(SpinnerType.BallAtom), errorMessage => this.alertifyService.message(errorMessage, {
      dismissOthers: true,
      messageType: MessageType.Error,
      position: Position.TopRight
    }))
    // take a backup of the filter as a clone.
    const filterClone = structuredClone(this.dataSource.filter);
    const sortClone = structuredClone(this.dataSource.sort);
    this.dataSource = new MatTableDataSource<List_Product>(allProducts.products);
    if (filterClone) {
        this.dataSource.filter = filterClone;
    }
    if (sortClone) {
        this.dataSource.sort = sortClone;
    }
    this.dataSource.paginator = this.paginator;
    this.paginator.length = allProducts.totalProductCount;
}

Вы совершенно правы. Я решил проблему, внеся несколько изменений в серверную часть. Большое спасибо за предоставленную ценную информацию.

Mustafasan 08.07.2024 21:57

Другие вопросы по теме