PrimeNG ——Let Filtering, Sorting and Lazy loading work together!

Preface

Sorting, filtering is not working well with Virtual scroll (Lazy loading) in PrimeNG data table. Actually with large data set ,primeNg table become hang, for this resolution we can implement Virtual scroll(Lazy loading). But there is a problem that Sorting, Filtering is not working well with lazy loading.
When a user is inserting some value in the global filter input or the column filter input or clicking the sorting button with the lazy loading on, the lazy loading function will be invoked. So we can invoke filtering and sorting function when the lazy loading function invoked.

In PrimeNG tables, when we enable lazy loading, there will be many problems, such as no sorting, no filtering, or sorting and filtering cannot occur within the scope of all data. However, primeNG's table blocks if loading a lot of data, and to solve this problem, we have to use lazy loading. So how do we fix this problem?
When a user clicks the sort button in the global search box or column search box, the lazy loading function will be called, so we can call custom sorting and filtering methods at this time.

Resolution

Firstly , let's create a function to implement global filtering
First, let's write a global filtering method

filterGlobal(row, value) {
    for(let i=0; i<this.columns.length; i++) {
        let column: Column = this.columns[i];
        if(row[column.name] == null) {
            continue;
        }
        let rowValue: String = row[column.name].toString().toLowerCase();
        if(rowValue.includes(value.toLowerCase()) {
            return true;
        }
    }
    return false
}

Next, let's create a filter to implement column
filtering

filterField(row, filter) {
    for (var columnName in filter) {
        if (row[columnName] == null) {
            return false;
      }
      let rowValue: String = row[columnName].toString().toLowerCase();
      let filterMatchMode: String = filter[columnName].matchMode;
      if (filterMatchMode.includes("contains") && rowValue.includes(filter[columnName].value.toLowerCase())) {
        return true;
      } else if (filterMatchMode.includes("startsWith") && rowValue.startsWith(filter[columnName].value.toLowerCase())) {
        return true;
      } else if (filterMatchMode.includes("in") && filter[columnName].value.includes(rowValue)) {
        return true;
      } else {
        return false;
      }
    }
  }


A comparison method for sorting

compareField(rowA, rowB, field: string): number {
    if (rowA[field] == null) return 1; 
    if (typeof rowA[field] === 'string') {
        return rowA[field].localeCompare(rowB[field]);
    }
    if (typeof rowA[field] === 'number') {
        if (rowA[field] > rowB[field]) return 1;
        else return -1;
    }
}

And then, we should create a lazy loading
function

loadLazy(event: LazyLoadEvent) {
    this.loading = true;
    this.filteredRows = this.dataSource.filter(row => this.filterField(row, event.filters));
    if(event.globalFilter.trim()) {
        this.filteredRows = this.filteredRows.filter(row => this.filterGlobal(row, event.globalFilter));
    }
    this.filteredRows.sort((a, b) => this.compareField(a, b, event.sortField) * event.sortOrder);
    this.gridData = this.filteredRows.slice(event.first, (event.first + event.rows));
    this.totalRows = this.filteredRows.length;
    this.loading = false;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325641208&siteId=291194637