web-dev-qa-db-fra.com

Filtrer sur plusieurs colonnes en utilisant un tuyau angulaire 2

J'essaie de filtrer les données Array basées sur plusieurs colonnes en utilisant un seul Pipe. Pour le moment, il filtre la première valeur de colonne. Veuillez vérifier mon code ci-dessous et aidez-moi à résoudre ce problème.

Mon code:

@Pipe({ name: "dataFilter", pure: false })
export class DataFilterPipe implements PipeTransform {
    transform(value: Array<any>, filter: any[]) {
        if (!filter) {
            return value;
        } else if (value) {
            return value.filter(item => {
                for (var i = 0; i < filter.length; i++) {
                    if (filter[i][1] == undefined) {
                        return true;
                    } else if ((typeof item[filter[i][0]] === 'string' || item[filter[i][0]] instanceof String) &&
                        (item[filter[i][0]].toLowerCase().indexOf(filter[i][1]) !== -1)) {
                        return true;
                    }
                    return false;
                }
            });
        }
    }
}

Je transmets des données comme dataFilter : [['column1',value1],['column2',value2],['column3',value3]].

15
Jeeten Parmar

Voici une solution utilisant l’objet passé en tant que filtre à plusieurs colonnes. J'ai trouvé cela plus pratique que de passer un tableau 2D:

    @Pipe({
        name: 'filter'
    })
    export class FilterPipe implements PipeTransform {
        transform(items: Array<any>, filter: {[key: string]: any }): Array<any> {
            return items.filter(item => {
                let notMatchingField = Object.keys(filter)
                                             .find(key => item[key] !== filter[key]);

                return !notMatchingField; // true if matches all fields
            });
        }
    }

Avoir un tableau d'objets à plusieurs colonnes:

this.people = [
  {name: 'John', age: 27, sex: 'male'},
  {name: 'Lara', age: 21, sex: 'female'},
  {name: 'Rick', age: 29, sex: 'male'},
  {name: 'Eva',  age: 27, sex: 'female'},
  {name: 'Mike', age: 27, sex: 'male'}
];

Et un filtre:

this.peopleFilter = {age: 27, sex: 'male'};

Utilisez-le comme:

 <div *ngFor="let person of people | filter: peopleFilter;"></div>

En conséquence, deux personnes correspondent à nos critères: John et Mike.

Voici le travail de plunker: Plusieurs colonnes de démonstration de pipe de filtre.

21
Seid Mehmedovic

Remplacez votre code comme ci-dessous,

 export class DataFilterPipe implements PipeTransform {
   transform(value: Item[], field: string, args: string): Item[]{
      let filter: string = args ? args.toLocaleLowerCase() : null;
      return filter ? value.filter((item : Item) =>
          Item[field].toLocaleLowerCase().indexOf(filter) != -1) : value;
   }
}

En page HTML,

 <tbody *ngFor="let item of items | dataFilter : columnName : value ">
2
Trusha

Vous pouvez voir le travail complet ArrayFilterPipe.ts @ http://TypeScript.io/uN29xRdF1Ag ou typescriptlang.org
J'ai également joint la compilation JS du TypeScript pour faciliter la visualisation de la sortie souhaitée.Faites-moi savoir si vous souhaitez que le code soit commenté ...

Le tableau d’options FYI est converti en objet avant d’effectuer le filtre, car il est beaucoup plus confortable que le tableau.

/* yours */
var option = [['column1',value1],['column2',value2],['column3',value3]];
/* mine */
var option = { column1: 'value1', column2: 'value2', column3: 'value3' };

static _arrayToObject(value: Array<Array<any>>): any {
    return (ArrayFilterPipe._isUndefined(value) || value == null) 
    ? value 
    : value.reduce((result, current) => {   
                    result[current[0]] = current[1]; 
                    return result; 
                } , {});
}

Vous pouvez également créer un filtre tableau/objet similaire à angular 1.x en vous inspirant de https://github.com/angular/angular.js/blob/master/src/ng/filter/filter.js

var ArrayFilterPipe = (function () {
    function ArrayFilterPipe() {
    }
    ArrayFilterPipe._isOfType = function (value, type) {
        return typeof (value) === type;
    };
    ArrayFilterPipe._isUndefined = function (value) {
        return ArrayFilterPipe._isOfType(value, ArrayFilterPipe.TYPES.UNDEFINED);
    };
    ArrayFilterPipe._isObject = function (value) {
        return ArrayFilterPipe._isOfType(value, ArrayFilterPipe.TYPES.OBJECT);
    };
    ArrayFilterPipe._isOrHasMatch = function (value, target) {
        return ArrayFilterPipe._isOfType(value, ArrayFilterPipe.TYPES.STRING) || ArrayFilterPipe._isOfType(target, ArrayFilterPipe.TYPES.STRING)
            ? value.toString().toLowerCase().indexOf(target.toString().toLowerCase()) >= 0
            : value == target;
    };
    ArrayFilterPipe._hasOptions = function (value, options) {
        return (ArrayFilterPipe._isUndefined(value) || ArrayFilterPipe._isUndefined(options) ? (ArrayFilterPipe._isUndefined(value) && ArrayFilterPipe._isUndefined(options))
            : (value === null || options == null) ? (value === null && options == null)
                : (Array.isArray(value) || Array.isArray(options)) ? false
                    : ArrayFilterPipe._isObject(value) ?
                        (ArrayFilterPipe._isObject(options)
                            ? Object.keys(options).every(function (key) { return value.hasOwnProperty(key) && ArrayFilterPipe._isOrHasMatch(value[key], options[key]); })
                            : Object.values(value).some(function (val) { return ArrayFilterPipe._isOrHasMatch(val, options); }))
                        : !ArrayFilterPipe._isObject(value) ?
                            (!ArrayFilterPipe._isObject(options)
                                ? ArrayFilterPipe._isOrHasMatch(value, options)
                                : false)
                            : false);
    };
    ArrayFilterPipe._arrayToObject = function (value) {
        return (ArrayFilterPipe._isUndefined(value) || value == null) ? value : value.reduce(function (result, current) {
            result[current[0]] = current[1];
            return result;
        }, {});
    };
    ArrayFilterPipe.prototype.transform = function (value, options) {
        if (!value || !Array.isArray(value) || ArrayFilterPipe._isUndefined(options) || options === null) {
            return value;
        }
        options = Array.isArray(options) ? ArrayFilterPipe._arrayToObject(options) : options;
        return value.filter(function (item) { return ArrayFilterPipe._hasOptions(item, options); });
    };
    return ArrayFilterPipe;
}());
ArrayFilterPipe.TYPES = {
    OBJECT: 'object',
    STRING: 'string',
    UNDEFINED: 'undefined'
};
/*
    TESTING
    --------------------------------------------------
*/
var pipe = new ArrayFilterPipe();
var array = [null, undefined, , true, 123123, 'Jeke HeNry', 'joe', 'joe hen', {}, [], { fake: 'hen' }, { name: 'hen' }, { name: 'johenrik', country: 'hen' }, { name: 'joe dick', city: 'hen' }, { name: 'Jeke HeNry', country: 'zxy' }];
var options = null;
/* REF:  http://stackoverflow.com/questions/11403107/capturing-javascript-console-log */
var oldLog = console.log;
console.log = function (message) {
    var _arguments = arguments;
    var div = Object.keys(arguments).map(function (key) { return Number(key); }).reduce(function (result, key) {
        result = result || document.createElement('div');
        var isJSON = (_arguments[key] != null && (typeof (_arguments[key]) === 'object' || Array.isArray(_arguments[key])));
        var span = document.createElement(isJSON ? 'pre' : 'span');
        span.innerHTML = isJSON ? JSON.stringify(_arguments[key], undefined) : _arguments[key].replace('\n', '</br></br>');
        result.appendChild(span);
        return result;
    }, null);
    document.body.appendChild(div);
    oldLog.apply(console, arguments);
};
function test() {
    console.log('options', options);
    console.log('result', pipe.transform(array, options));
}
console.log('case : 01');
console.log('---------------------------------------------------');
options = 'hen';
test();
console.log('\ncase : 02');
console.log('---------------------------------------------------');
options = { name: 'hen' };
test();
options = [['name', 'hen']];
test();
console.log('\ncase : 03');
console.log('---------------------------------------------------');
options = { name: 'hen', country: 'hen' };
test();
options = [['name', 'hen'], ['country', 'hen']];
test();
console.log('\ncase : 04');
console.log('---------------------------------------------------');
options = { name: 'hen', city: 'hen', fake: true };
test();
options = [['name', 'hen'], ['country', 'hen'], ['fake', true]];
test();

0