如何在 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'});