简体   繁体   English

在angular 7中动态html引导程序表中实现排序和过滤的最佳方法是什么?

[英]What is the best way to implement sorting and filtering in a dynamic html bootstrap table in angular 7?

我想在角度为7的表格中实现排序和过滤。使用一些可用的解决方案(如角度材料)或构建简单的排序和过滤管道是一个好主意。

I found myself in a situation like this, i was already using angular material, so i opted to continue with it. 我发现自己处于这种情况,我已经使用了有角度的材料,所以我选择继续使用它。

This is how i handled the search and the sort of the table 这就是我处理搜索和表格排序的方式

I created a class a datasource class to handle the http data, inside it i call the service that makes the http data request 我创建了一个类来处理http数据的数据类,我在其中调用了发出http数据请求的服务

import {Domanda} from '../models';
import {DataSource} from '@angular/cdk/table';
import {BehaviorSubject, Observable, of} from 'rxjs';
import {catchError, finalize} from 'rxjs/operators';
import {CollectionViewer} from '@angular/cdk/collections';
import {ApiService} from './api.service';


export class ListaDomandeDatasource implements DataSource<Domanda> {

  private domandeSubject = new BehaviorSubject<Domanda[]>([]);


// Gestisce il caricamento della tabella
  private loadingSubject = new BehaviorSubject<boolean>(false);

  public loading$ = this.loadingSubject.asObservable();

  constructor(private apiService: ApiService) {

  }

  cercaDomande(idConcorso: number,
               keywords: string,
               sortOrder: string,
               pageIndex: number,
               pageSize: number) {

    this.loadingSubject.next(true);

    this.apiService.cercaDomande(idConcorso, keywords, sortOrder,
      pageIndex, pageSize).pipe(
      catchError(() => of([])),
      finalize(() => this.loadingSubject.next(false))
    )
      .subscribe(lessons => this.domandeSubject.next(lessons));

  }

  connect(collectionViewer: CollectionViewer): Observable<Domanda[]> {
    console.log('Connecting data source');
    return this.domandeSubject.asObservable();
  }

  disconnect(collectionViewer: CollectionViewer): void {
    this.domandeSubject.complete();
    this.loadingSubject.complete();
  }

}

In the component where the table is defined i simply play with rxjs to listen from input, but actually the logic part is all do it by the backend. 在定义表的组件中,我只需使用rxjs来监听输入,但实际上逻辑部分都是由后端完成的。

import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {Concorso} from '../../../../core/models';
import {MatPaginator, MatSort} from '@angular/material';
import {ActivatedRoute, Router} from '@angular/router';
import {ApiService} from '../../../../core/services';
import {ListaDomandeDatasource} from '../../../../core/services/lista-domande.datasource';
import {fromEvent, merge} from 'rxjs';
import {debounceTime, distinctUntilChanged, tap} from 'rxjs/operators';

@Component({
  selector: 'app-lista-domande',
  templateUrl: './concorso.component.html',
  styleUrls: ['./concorso.component.scss']
})
export class ConcorsoComponent implements OnInit, AfterViewInit {
  nomeColonne: string[] = ['id', 'nominativo', 'dataNascita', 'dataProva', 'nomeProva', 'open'];

  dataSource: ListaDomandeDatasource;
  concorso: Concorso; // Risultato del resolver esistenza concorso


  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
  @ViewChild(MatSort, { static: true }) sort: MatSort;
  @ViewChild('input', { static: true }) input: ElementRef;

  constructor(private api: ApiService,
              private router: Router,
              private route: ActivatedRoute) {

  }


  ngOnInit() {

    /* Se si resta sulla stessa pagina e si cambiano solo i parametri la pagina non viene ricaricata, dunque ngOnInit non viene triggerato,
    * per ovviare a ciò resto in ascolto dei parametri che cambiano e chiamo la lista delle domande */
    this.route.params.subscribe(
      () => {
        this.concorso = this.route.snapshot.data.concorso;
      }
    );

    // Istanzio il datasource passandogli il service
    this.dataSource = new ListaDomandeDatasource(this.api);

    this.dataSource.cercaDomande(this.concorso.id, '', 'asc', 0, 3);

  }

  ngAfterViewInit() {

    this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);

    // Triggero evento input nella searchbar
    fromEvent(this.input.nativeElement, 'keyup')
      .pipe(
        debounceTime(150),
        distinctUntilChanged(),
        tap(() => {
          this.paginator.pageIndex = 0;

          this.CaricaPaginaDomande();
        })
      )
      .subscribe();

    merge(this.sort.sortChange, this.paginator.page)
      .pipe(
        tap(() => this.CaricaPaginaDomande())
      )
      .subscribe();

  }

  CaricaPaginaDomande() {
    this.dataSource.cercaDomande(
      this.concorso.id,
      this.input.nativeElement.value,
      this.sort.direction,
      this.paginator.pageIndex,
      this.paginator.pageSize);
  }

  GotoDomanda(id) {
    return 'domanda/' + id;
  }

}

And this is the html part: 这是html部分:

<h2>CONCORSO: {{concorso.id}}</h2>

<div fxLayout="column">


  <mat-form-field>
    <label for="searchbar"></label>
    <input matInput id="searchbar" placeholder="Cerca candidato per il suo identificativo" #input>
    <mat-icon matPrefix>search</mat-icon>
  </mat-form-field>


  <div class="spinner-container" *ngIf="dataSource.loading$ | async">
    <mat-spinner></mat-spinner>
  </div>

  <table fxFill
         mat-table [dataSource]="dataSource"
         matSort matSortActive="created" matSortDisableClear matSortDirection="asc">

    <!-- Colonna id domande-->
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef>#</th>
      <td mat-cell *matCellDef="let row">{{row.DomandaConcorso.IdDomanda}}</td>
    </ng-container>

    <!-- Colonna cognome nome canditato -->
    <ng-container matColumnDef="nominativo">
      <th mat-header-cell *matHeaderCellDef>Nominativo</th>
      <td mat-cell *matCellDef="let row">{{row.Anagrafica.Cognome}} {{row.Anagrafica.Nome}}</td>
    </ng-container>

    <!-- Colonna data di nascita candidato -->
    <ng-container matColumnDef="dataNascita">
      <th mat-header-cell *matHeaderCellDef>Data di nascita</th>
      <td mat-cell *matCellDef="let row">{{row.Anagrafica.DataNascita}}</td>
    </ng-container>

    <!-- Colonna data prova candidato -->
    <ng-container matColumnDef="dataProva">
      <th mat-header-cell *matHeaderCellDef>Data prova</th>
      <td mat-cell *matCellDef="let row">{{row.prove[2].dataProva}}</td>
    </ng-container>

    <!-- Colonna nome ultima prova -->
    <ng-container matColumnDef="nomeProva">
      <th mat-header-cell *matHeaderCellDef>Data prova</th>
      <td mat-cell *matCellDef="let row">{{row.prove[2].nomeProva}}</td>
    </ng-container>


    <!-- Colonna bottone apri singola domande -->
    <ng-container matColumnDef="open">
      <th mat-header-cell *matHeaderCellDef></th>
      <td mat-cell *matCellDef="let row" >
        <button [routerLink]="GotoDomanda(row.DomandaConcorso.IdDomanda)"  mat-flat-button>VISUALIZZA</button>
      </td>
    </ng-container>


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

  <mat-paginator [length]="20" [pageSize]="3"
                 [pageSizeOptions]="[3, 5, 10]"></mat-paginator>

</div>

Al this things can't be done without reading the docs of datatable: https://material.angular.io/components/categories/tables 如果没有阅读数据表的文档,就无法做到这一点: https//material.angular.io/components/categories/tables

If you have any other question tell me. 如果您有任何其他问题告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM