2017-06-16 1 views
1

En résumé: existe-t-il un moyen d'implémenter un comparateur personnalisé pour les filtres de colonne de nombres?Comparateur personnalisé de comparateur numérique

longue histoire:

J'utilise grille ag angulaire (2). Je donne mes propres composants pour les cellules dans mon ag-réseau:

let column = { 
    headerName: column.header, 
    field: column.id, 
    cellRendererFramework: DynamicComponent, 
    filter: this.convertFormatToFilterType(column.format) // returns "text", "number" or "date" 
} 

Afin de rendre les filtres obtenir des valeurs de mes cellules correctement je fournir des comparateurs personnalisés (celui-ci est pour les filtres de colonne de texte):

if (c.filter === "text") 
    c['filterParams'] = { 
    textCustomComparator: (filter, cell, filterText): boolean => { 
    var filterTextLowerCase = filterText.toLowerCase(); 
    var valueLowerCase = cell.value.toString().toLowerCase(); 
    switch (filter) { 
     case 'contains': 
     return valueLowerCase.indexOf(filterTextLowerCase) >= 0; 
     case 'notContains': 
     return valueLowerCase.indexOf(filterTextLowerCase) === -1; 
     case 'equals': 
     return valueLowerCase === filterTextLowerCase; 
     case 'notEqual': 
     return valueLowerCase != filterTextLowerCase; 
     case 'startsWith': 
     return valueLowerCase.indexOf(filterTextLowerCase) === 0; 
     case 'endsWith': 
     var index = valueLowerCase.lastIndexOf(filterTextLowerCase); 
     return index >= 0 && index === (valueLowerCase.length - filterTextLowerCase.length); 
     default: 
     // should never happen 
     console.warn('invalid filter type ' + filter); 
      return false; 
     } 
     } 
    }; 

Vous pouvez voir que j'ai besoin d'accéder à la valeur de la cellule en utilisant "cell.value". Le code ci-dessus fonctionne bien. Ce qui me pose problème, c'est de fournir des fonctionnalités similaires pour les filtres de colonnes de nombres - ils ne semblent pas utiliser de comparateur personnalisé. Par conséquent, ce qui se passe, le filtre essaie d'accéder directement à la valeur de la cellule au lieu d'utiliser "cell.value".

Alors, existe-t-il un moyen de mettre en œuvre un comparateur personnalisé pour les filtres de colonnes numériques? Ou, sinon, d'une autre manière je peux obtenir la valeur de mes cellules correctement dans ce cas?

Répondre

0

Ce que je fini par faire est la mise en œuvre d'un ag-grid custom filter component

import { Component, ViewChild, ViewContainerRef } from '@angular/core'; 

import { IFilterParams, IDoesFilterPassParams, RowNode, IAfterGuiAttachedParams } from 'ag-grid/main'; 
import { IFilterAngularComp } from 'ag-grid-angular/main'; 

// https://www.ag-grid.com/javascript-grid-filter-component/#gsc.tab=0/Angular Filtering 
// create your filter as a Angular component 
@Component({ 
    selector: 'filter-cell', 
    template: ` 
    <select #select (ngModelChange)="onSelectChange($event)" [ngModel]="operator"> 
     <option value="eq">Equals</option> 
     <option value="neq">Not equal</option> 
     <option value="lt">Less than</option> 
     <option value="lte">Less than or equals</option> 
     <option value="gt">Greater than</option> 
     <option value="gte">Greater than or equals</option> 
     <option value="inrange">In range</option> 
    </select> 

    <br> 

    <input #input (ngModelChange)="onChange($event)" [ngModel]="text"> 
    <br> 
    <div *ngIf='operator === "inrange"'> 
     <input #input2 (ngModelChange)="onChange2($event)" [ngModel]="text2"> 
    </div> 
    `, 
    styles: ['select { margin: 2px 4px; }', 'input { height: 26px; margin: 2px 4px; }'] 
}) 
export class GridNumberFilterComponent implements IFilterAngularComp { 
    private params: IFilterParams; 
    private valueGetter: (rowNode: RowNode) => any; 
    public operator: string = 'eq'; 
    public text: string = ''; 
    public text2: string = ''; 

    @ViewChild('select', { read: ViewContainerRef }) public select; 
    @ViewChild('input', { read: ViewContainerRef }) public input; 
    @ViewChild('input2', { read: ViewContainerRef }) public input2; 

    agInit(params: IFilterParams): void { 
     this.params = params; 
     this.valueGetter = params.valueGetter; 
    } 

    isFilterActive(): boolean { 
     return this.text !== null && this.text !== undefined && this.text !== ''; 
    } 

    doesFilterPass(params: IDoesFilterPassParams): boolean { 
     let cellNumber = Number(this.valueGetter(params.node).value); 
     let filterNumber = this.text ? Number(this.text) : -Infinity; 
     let filterNumber2 = this.text2 ? Number(this.text2) : Infinity; 

     switch (this.operator) { 
      case 'eq': return cellNumber === filterNumber; 
      case 'neq': return cellNumber !== filterNumber; 
      case 'lt': return cellNumber < filterNumber; 
      case 'lte': return cellNumber <= filterNumber; 
      case 'gt': return cellNumber > filterNumber; 
      case 'gte': return cellNumber >= filterNumber; 
      case 'inrange': return cellNumber >= filterNumber && cellNumber <= filterNumber2; 

      default: return true; 
     } 
    } 

    getModel(): any { 
     return { value: this.text }; 
    } 

    setModel(model: any): void { 
     this.text = model ? model.value : ''; 
    } 

    afterGuiAttached(params: IAfterGuiAttachedParams): void { 
     this.input.element.nativeElement.focus(); 
    } 

    componentMethod(message: string): void { 
     alert(`Alert from PartialMatchFilterComponent ${message}`); 
    } 

    onSelectChange(newValue): void { 
     if (this.operator !== newValue) { 
      this.operator = newValue; 
      this.params.filterChangedCallback(); 
     } 
    } 

    onChange(newValue): void { 
     if (this.text !== newValue) { 
      this.text = newValue; 
      this.params.filterChangedCallback(); 
     } 
    } 

    onChange2(newValue): void { 
     if (this.text2 !== newValue) { 
      this.text2 = newValue; 
      this.params.filterChangedCallback(); 
     } 
    } 
} 

que j'ajouter à ma colonne comme ceci:

let column = { 
    headerName: column.header, 
    field: column.id, 
    cellRendererFramework: DynamicComponent, 
    filterFramework: GridNumberFilterComponent 
}