如何在 Tabulator 的树结构中过滤 children?
How to filter children in tree structure in Tabulator?
我尝试在 Tabulator 树结构上调用 setFilter
函数,以过滤掉项目。好像只过滤掉topparents。知道如何使它适用于任何级别(任何 children 或 parents)吗? http://tabulator.info/docs/4.1/tree 没有详细说明过滤的工作原理。
函数
table.setFilter('id', '=', 214659)
没有返回任何东西...
树形结构
[
{
"level":0,
"name":"word1",
"id":125582,
"_children":[
{
"level":1,
"name":"word6",
"id":214659
},
{
"level":1,
"name":"word7",
"id":214633
},
{
"level":1,
"name":"word2",
"id":214263,
"_children":[
{
"level":2,
"name":"word8",
"id":131673
},
{
"level":2,
"name":"word9",
"id":125579
},
{
"level":2,
"name":"word10",
"id":125578
},
{
"level":2,
"name":"word4",
"id":172670,
"_children":[
{
"level":3,
"name":"word13",
"id":172669
},
{
"level":3,
"name":"word14",
"id":174777
},
{
"level":3,
"name":"word5",
"id":207661,
"_children":[
{
"level":4,
"name":"word15",
"id":216529
},
{
"level":4,
"name":"word16",
"id":223884,
"_children":[
{
"level":5,
"name":"word17",
"id":223885,
"_children":[
{
"level":6,
"name":"word18",
"id":229186,
"_children":[
{
"level":7,
"name":"word19",
"id":219062
},
{
"level":7,
"name":"word20",
"id":222243
}
]
}
]
}
]
}
]
}
]
},
{
"level":2,
"name":"word3",
"id":214266,
"_children":[
{
"level":3,
"name":"word11",
"id":216675
},
{
"level":3,
"name":"word12",
"id":216671
}
]
}
]
}
]
}
]
经过一番搜索后,我发现了 lodash
库的一个扩展,名为 deepdash
,它具有深层过滤功能,并且运行良好。
您将有 2 个新的依赖项,但我认为它会满足您的目的。
查看有关如何安装它们的文档 here
在此处的代码片段中,您可以在日志中看到结果。我也做了一个沙箱here
这是一个 ID 列表,一个或多个。
如果您只需要为一个值更改条件。 return _.indexOf(idList, value.id) !== -1;
到 return id===value.id;
其中 id
是您的 id
变量
此外,在查看 Tabulator 的文档后,它们只有一级过滤,即使您编写自己的自定义过滤器也无济于事,因为它需要一个 bool 值来呈现行或不呈现行。但只针对第一层,所以如果父对象不是你要找的子对象,就会被忽略。您唯一的选择是过滤制表符之外的数据。
const data = [
{
level: 0,
name: "word1",
id: 125582,
_children: [
{
level: 1,
name: "word6",
id: 214659
},
{
level: 1,
name: "word7",
id: 214633
},
{
level: 1,
name: "word2",
id: 214263,
_children: [
{
level: 2,
name: "word8",
id: 131673
},
{
level: 2,
name: "word9",
id: 125579
},
{
level: 2,
name: "word10",
id: 125578
},
{
level: 2,
name: "word4",
id: 172670,
_children: [
{
level: 3,
name: "word13",
id: 172669
},
{
level: 3,
name: "word14",
id: 174777
},
{
level: 3,
name: "word5",
id: 207661,
_children: [
{
level: 4,
name: "word15",
id: 216529
},
{
level: 4,
name: "word16",
id: 223884,
_children: [
{
level: 5,
name: "word17",
id: 223885,
_children: [
{
level: 6,
name: "word18",
id: 229186,
_children: [
{
level: 7,
name: "word19",
id: 219062
},
{
level: 7,
name: "word20",
id: 222243
}
]
}
]
}
]
}
]
}
]
},
{
level: 2,
name: "word3",
id: 214266,
_children: [
{
level: 3,
name: "word11",
id: 216675
},
{
level: 3,
name: "word12",
id: 216671
}
]
}
]
}
]
}
];
const idList = [214659];
const found = _.filterDeep(
data,
function(value) {
return _.indexOf(idList, value.id) !== -1;
},
{ tree: true, childrenPath: '_children' }
);
console.log(found);
<script src="https://cdn.jsdelivr.net/npm/lodash/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/deepdash/browser/deepdash.min.js"></script>
<script>
deepdash(_);
</script>
这是一个递归函数,它将找到父 and/or 个符合条件的子项。
在此示例中,如果子项匹配,则父项将始终显示 - 即使父项本身不匹配 - 但您可以通过调整测试中的测试轻松地根据需要调整代码for 循环。
var filterTree = function (data, filter) {
if (data['_children'] && data['_children'].length > 0) {
for (var i in data['_children']) {
return data[filter.field] == filter.value || filterTree(data['_children'][i], filter);
}
}
return data[filter.field] == filter.value;
};
将此函数作为自定义过滤器回调调用:
table.setFilter(filterTree, {field:'myfield', type:'=', value:'myvalue'});
请注意,这只是示例代码,重点介绍递归过滤树的逻辑。以上仅适用于“=”比较。
在实际情况中,您将不得不实现更多代码来处理制表符支持的所有其他运算符,因为在 Javascript 中无法进行动态运算符分配。您也许可以考虑 eval() 但那是另一回事了。
有关动态运算符分配的更多信息,请点击此处:
Are Variable Operators Possible?
这是处理所有制表符运算符的实现示例:
// Operators
var compare = {
'=': function(a, b) { return a == b },
'<': function(a, b) { return a < b },
'<=': function(a, b) { return a <= b },
'>': function(a, b) { return a > b },
'>=': function(a, b) { return a >= b },
'!=': function(a, b) { return a != b },
'like': function(a, b) { return a.includes(b)}
};
// Filter function
var filterTree = function (data, filter) {
if (data['_children'] && data['_children'].length > 0) {
for (var i in data['_children']) {
return compare[filter.type](data[filter.field], filter.value) || filterTree(data['_children'][i], filter);
}
}
return compare[filter.type](data[filter.field], filter.value);
};
// Set a filter. The operator can now be provided dynamically
table.setFilter(filterTree, {field:'myfield', type: '>=', value:'myvalue'});
我尝试在 Tabulator 树结构上调用 setFilter
函数,以过滤掉项目。好像只过滤掉topparents。知道如何使它适用于任何级别(任何 children 或 parents)吗? http://tabulator.info/docs/4.1/tree 没有详细说明过滤的工作原理。
函数
table.setFilter('id', '=', 214659)
没有返回任何东西...
树形结构
[
{
"level":0,
"name":"word1",
"id":125582,
"_children":[
{
"level":1,
"name":"word6",
"id":214659
},
{
"level":1,
"name":"word7",
"id":214633
},
{
"level":1,
"name":"word2",
"id":214263,
"_children":[
{
"level":2,
"name":"word8",
"id":131673
},
{
"level":2,
"name":"word9",
"id":125579
},
{
"level":2,
"name":"word10",
"id":125578
},
{
"level":2,
"name":"word4",
"id":172670,
"_children":[
{
"level":3,
"name":"word13",
"id":172669
},
{
"level":3,
"name":"word14",
"id":174777
},
{
"level":3,
"name":"word5",
"id":207661,
"_children":[
{
"level":4,
"name":"word15",
"id":216529
},
{
"level":4,
"name":"word16",
"id":223884,
"_children":[
{
"level":5,
"name":"word17",
"id":223885,
"_children":[
{
"level":6,
"name":"word18",
"id":229186,
"_children":[
{
"level":7,
"name":"word19",
"id":219062
},
{
"level":7,
"name":"word20",
"id":222243
}
]
}
]
}
]
}
]
}
]
},
{
"level":2,
"name":"word3",
"id":214266,
"_children":[
{
"level":3,
"name":"word11",
"id":216675
},
{
"level":3,
"name":"word12",
"id":216671
}
]
}
]
}
]
}
]
经过一番搜索后,我发现了 lodash
库的一个扩展,名为 deepdash
,它具有深层过滤功能,并且运行良好。
您将有 2 个新的依赖项,但我认为它会满足您的目的。 查看有关如何安装它们的文档 here
在此处的代码片段中,您可以在日志中看到结果。我也做了一个沙箱here
这是一个 ID 列表,一个或多个。
如果您只需要为一个值更改条件。 return _.indexOf(idList, value.id) !== -1;
到 return id===value.id;
其中 id
是您的 id
变量
此外,在查看 Tabulator 的文档后,它们只有一级过滤,即使您编写自己的自定义过滤器也无济于事,因为它需要一个 bool 值来呈现行或不呈现行。但只针对第一层,所以如果父对象不是你要找的子对象,就会被忽略。您唯一的选择是过滤制表符之外的数据。
const data = [
{
level: 0,
name: "word1",
id: 125582,
_children: [
{
level: 1,
name: "word6",
id: 214659
},
{
level: 1,
name: "word7",
id: 214633
},
{
level: 1,
name: "word2",
id: 214263,
_children: [
{
level: 2,
name: "word8",
id: 131673
},
{
level: 2,
name: "word9",
id: 125579
},
{
level: 2,
name: "word10",
id: 125578
},
{
level: 2,
name: "word4",
id: 172670,
_children: [
{
level: 3,
name: "word13",
id: 172669
},
{
level: 3,
name: "word14",
id: 174777
},
{
level: 3,
name: "word5",
id: 207661,
_children: [
{
level: 4,
name: "word15",
id: 216529
},
{
level: 4,
name: "word16",
id: 223884,
_children: [
{
level: 5,
name: "word17",
id: 223885,
_children: [
{
level: 6,
name: "word18",
id: 229186,
_children: [
{
level: 7,
name: "word19",
id: 219062
},
{
level: 7,
name: "word20",
id: 222243
}
]
}
]
}
]
}
]
}
]
},
{
level: 2,
name: "word3",
id: 214266,
_children: [
{
level: 3,
name: "word11",
id: 216675
},
{
level: 3,
name: "word12",
id: 216671
}
]
}
]
}
]
}
];
const idList = [214659];
const found = _.filterDeep(
data,
function(value) {
return _.indexOf(idList, value.id) !== -1;
},
{ tree: true, childrenPath: '_children' }
);
console.log(found);
<script src="https://cdn.jsdelivr.net/npm/lodash/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/deepdash/browser/deepdash.min.js"></script>
<script>
deepdash(_);
</script>
这是一个递归函数,它将找到父 and/or 个符合条件的子项。
在此示例中,如果子项匹配,则父项将始终显示 - 即使父项本身不匹配 - 但您可以通过调整测试中的测试轻松地根据需要调整代码for 循环。
var filterTree = function (data, filter) {
if (data['_children'] && data['_children'].length > 0) {
for (var i in data['_children']) {
return data[filter.field] == filter.value || filterTree(data['_children'][i], filter);
}
}
return data[filter.field] == filter.value;
};
将此函数作为自定义过滤器回调调用:
table.setFilter(filterTree, {field:'myfield', type:'=', value:'myvalue'});
请注意,这只是示例代码,重点介绍递归过滤树的逻辑。以上仅适用于“=”比较。
在实际情况中,您将不得不实现更多代码来处理制表符支持的所有其他运算符,因为在 Javascript 中无法进行动态运算符分配。您也许可以考虑 eval() 但那是另一回事了。
有关动态运算符分配的更多信息,请点击此处: Are Variable Operators Possible?
这是处理所有制表符运算符的实现示例:
// Operators
var compare = {
'=': function(a, b) { return a == b },
'<': function(a, b) { return a < b },
'<=': function(a, b) { return a <= b },
'>': function(a, b) { return a > b },
'>=': function(a, b) { return a >= b },
'!=': function(a, b) { return a != b },
'like': function(a, b) { return a.includes(b)}
};
// Filter function
var filterTree = function (data, filter) {
if (data['_children'] && data['_children'].length > 0) {
for (var i in data['_children']) {
return compare[filter.type](data[filter.field], filter.value) || filterTree(data['_children'][i], filter);
}
}
return compare[filter.type](data[filter.field], filter.value);
};
// Set a filter. The operator can now be provided dynamically
table.setFilter(filterTree, {field:'myfield', type: '>=', value:'myvalue'});