
هل تحتاج غالبًا إلى كتابة معالجات التصفية لبياناتك؟ يمكن أن تكون صفائف لرسم الجداول والبطاقات والقوائم - أي شيء.
عندما يكون الترشيح ثابتًا ، يكون كل شيء بسيطًا. يتميز معيار 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 . .

, . .
, .