Angular 6 multi field filter

梦想的初衷 提交于 2019-12-13 03:50:49

问题


I'm currently working on angular 6 app. I have a huge list of articles and want to do some filtering upon it. Right now it works real-time, there is no button to submit your filter options, it all happens as you type. I figure a way, but it has still some issues I can fix, but doesn't like the way I did it. I'm sure, there has to be something more elegant.

For better imagination those articles have category, title, author, tags. I am able to filter them according to category lets say... but I want to do some kind of filtering.

Example: Filter all articles from category 'sports', then filter all articles having substring 'goal' in title from that already filtered array, then filter those whos author is 'john' and then filter all with tag 'hockey'.

I ended up with huge amount of IF statements, which is not the right approach I would say. Can you please recommend me some better way to do this?


回答1:


This is what you could do to create a multifilter without many if statements.

Step one: Create an object that performs various comparison functions:

let compareFunctions = {
    equal: function(a,b) {
        return a === b;
    },
    in: function(a,b){
        return a.indexOf(b) !== -1
    }
}

Step two: Create a function that has the following parameters:

  1. key - The key of the field of your record you want to filter.
  2. value - The value you want to filter by
  3. compareFn - The comparison function to be used for this field

This function returns a function that executes the condition.

function condition(key, value, comparFn = compareFunctions.equal) {
    return function(data) {
        return comparFn(data[key],value);
    }
}

Step three: Create an array with "condition" functions representing your filter values:

let filterArray = [
    condition('category', 'sports'),
    condition('title', 'goal', compareFunctions.in),
    condition('author', 'john'),
    condition('tags', 'hokey', compareFunctions.in),
]

Step four: Filter your record by calling your array of conditions functions for each entry and evaluating the result of each condition:

let result = dataset.filter(y => {
    let resolved = filterArray.map(x => x(y))
    return resolved.every(x => x === true);
})

Full example code:

let compareFunctions = {
    equal: function(a,b) {
        return a === b;
    },
    in: function(a,b){
        return a.indexOf(b) !== -1
    }
}

function condition(key, value, comparFn = compareFunctions.equal) {
    return function(data) {
        return comparFn(data[key],value);
    }
}

let dataset = [
    {
        category: "sports",
        title: "goal goal goal",
        author: "john",
        tags: ["hokey", "ice-hokey"]
    },
    {
        category: "news",
        title: "bla bla",
        author: "Timo",
        tags: ["news"]
    },
    {
        category: "news",
        title: "blub blub",
        author: "alex",
        tags: ["hokey", "ice-hokey"]
    },
    {
        category: "sports",
        title: "Kölner Haie bla bla",
        author: "Timo",
        tags: ["hokey", "ice-hokey"]
    }
]

let filterArray = [
    condition('category', 'sports'),
    condition('title', 'goal', compareFunctions.in),
    condition('author', 'john'),
    condition('tags', 'hokey', compareFunctions.in),
]

//console.log(filterArray)

let result = dataset.filter(y => {
    let resolved = filterArray.map(x => x(y))
    return resolved.every(x => x === true);
})

console.log(result)


来源:https://stackoverflow.com/questions/53250009/angular-6-multi-field-filter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!