
您是否经常需要为数据编写过滤器处理程序?它可以是绘图表,卡片,列表等的数组。
如果过滤是静态的,那么一切都很简单。标准功能map
,filter
并reduce
完全够用。但是,如果数据具有复杂的结构或嵌套,并且过滤器可能有很多规则,该怎么办?可以重复规则,可以更改数据,并且出现的过滤器控件越多,处理程序代码将越复杂和不稳定。
如何解决日益复杂的问题?
我本人在开发可处理大量数据的应用程序时遇到了这个问题。逐渐添加了越来越多的新过滤器。
, . . , . , . - .
, .
, :
ng-table
— . .List.js
— ng-table, .filter.js
— , , .Isotope
— DOM . .
, :
- .
- .
- .
- ,
and
or
. - . .
- ( , , , , , )
awesome-data-filter.
, , .
.
npm install awesome-data-filter
.
, :
const users = [
{
age: 31,
name: "Marina Gilmore",
},
{
age: 34,
name: "Joyner Mccray",
},
{
age: 23,
name: "Inez Copeland",
},
{
age: 23,
name: "Marina Mitchell",
},
{
age: 25,
name: "Prince Spears",
},
];
:
const filterValue = {
age: 23,
searchText: "mari",
};
, .
:
matchText
— ;equalProp
— ;
betweenDates
— ;equalOneOf
— ;someInArray
— ;isEmptyArray
— ;lessThen
— , ;moreThen
— , ;not
— .
matchText
equalProp
.
:
filterField
— ;elementField
— .
import {
buildFilter,
elementField,
filterField,
} from "awsome-data-filter";
import { matchText, equalProp } from "awsome-data-filter/rules";
import { and } from "awsome-data-filter/conditions";
const filter = buildFilter({
rules: {
elementFilter: and([
matchText(filterField("searchText"), elementField("name")),
equalProp(filterField("age"), elementField("age")),
]),
},
});
const { elements } = filter(
filterValue,
{
groups: [],
elements: users,
},
);
console.log(elements);
filter
groups
elements
.
, . .

, , elements
.
and
or
, 2 .
import {
buildFilter,
elementField,
filterField,
} from "awsome-data-filter";
import { matchText, equalProp } from "awsome-data-filter/rules";
import { or } from "awsome-data-filter/conditions";
const filter = buildFilter({
rules: {
elementFilter: or([
matchText(filterField("searchText"), elementField("name")),
equalProp(filterField("age"), elementField("age")),
]),
},
});
const { elements } = filter(
filterValue,
{
groups: [],
elements: users,
},
);
console.log(elements);
filterField
, elementField
.
constValue
.
or(..., matchText, [and([..., matchText, ...]), or([..., ...])])
. :
const dataList = [
{
groupName: "first group",
list: [
{ age: 31, name: "Marina" },
{ age: 23, name: "Fabio" },
],
},
{
groupName: "second group",
groups: [
{
groupName: "third group",
list: [],
groups: [
{
groupName: "fourth group",
list: [{ age: 42, name: "Li" }],
},
],
},
],
list: [
{ age: 41, name: "Marina" },
{ age: 29, name: "Inez" },
{ age: 33, name: "Marina" },
],
},
{
groupName: "fifth group",
list: [
{ age: 21, name: "Dmitriy" },
{ age: 22, name: "Li" },
{ age: 45, name: "Mitchell" },
],
},
];
traversal
:
import {
buildFilter,
elementField,
filterField,
} from "awsome-data-filter";
import { matchText } from "awsome-data-filter/rules";
const filter = buildFilter({
traversal: {
getChildrenFunc: group => group.list,
setChildrenFunc: (group, list) => ({ ...group, list }),
getGroupsFunc: group => group.groups,
setGroupsFunc: (group, groups) => ({ ...group, groups }),
},
rules: {
elementFilter: matchText(filterField("searchText"), elementField("name")),
},
});
const filterValue = {
searchText: "li",
};
const { groups } = filter(filterValue, {
groups: dataList,
elements: [],
});
console.log(groups);
elementFilter
, . groupFilter
.
import {
buildFilter,
elementField,
filterField,
} from "awsome-data-filter";
import { matchText } from "awsome-data-filter/rules";
const filter = buildFilter({
traversal: {
getChildrenFunc: group => group.list,
setChildrenFunc: (group, list) => ({ ...group, list }),
getGroupsFunc: group => group.groups,
setGroupsFunc: (group, groups) => ({ ...group, groups }),
},
rules: {
elementFilter: matchText(filterField("searchText"), elementField("name")),
groupFilter: matchText(filterField("groupName"), elementField("groupName")),
},
});
const filterValue = {
searchText: "li",
groupName: "fi",
};
const { groups } = filter(filterValue, {
groups: dataList,
elements: [],
});
console.log(groups);
first group
, , , .
fifth group
, , .
. :
const standardStrategy: StrategiesFilterInterface = {
elementHandler: ({
element,
tools: {
isGroupFilterIsActive,
applyElementFilter
},
}) => {
if (isGroupFilterIsActive) return null;
if (!applyElementFilter) return element;
return applyElementFilter(element, true) ? element : null;
},
groupHandler: ({
element: group,
originalElement: originalGroup,
tools: {
isGroupFilterIsActive,
applyElementFilter,
getIsGroupFilterHaveMatch,
getGroupsFunc,
getChildrenFunc,
setChildrenFunc,
},
}) => {
let newChildren = [];
let originalChildren = [];
const children = getChildrenFunc(group);
const childrenExists = !!children;
if (children) {
originalChildren = [...children];
newChildren = originalChildren.filter(element =>
applyElementFilter
? applyElementFilter(element, !isGroupFilterIsActive)
: !isGroupFilterIsActive,
);
}
if (!newChildren.length && getIsGroupFilterHaveMatch(group)) {
return originalGroup;
}
if (childrenExists) {
group = setChildrenFunc(group, newChildren);
}
const newGroups = getGroupsFunc(group);
const isGroupsExists = !!(newGroups && newGroups.length);
const isElementExists = !!(newChildren && newChildren.length);
return isElementExists || isGroupsExists ? group : null;
},
};
, filterStrategy
.
awesome-data-filter . .

, . .
, .