【问题标题】:How to filter children in tree structure in Tabulator?如何在 Tabulator 中过滤树结构中的子项?
【发布时间】:2020-03-20 17:59:54
【问题描述】:

我尝试在我的制表树结构上调用setFilter 函数,以过滤掉项目。它似乎只过滤掉顶级父母。知道如何使这项工作适用于任何级别(任何孩子或父母)吗? 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
                     }
                  ]
               }
            ]
         }
      ]
   }
]

【问题讨论】:

  • 你不能在制表符之外过滤数据并只渲染新数据吗?以前没用过,就是问问。考虑到它仍然是 javascript 它应该可以工作
  • 什么是有效的方法?我的 JSON 中有大约 100 万条记录。
  • 迭代和递归函数......这取决于过滤条件是什么以及您要返回什么。
  • id 等于 214659 的任何记录,例如...

标签: tabulator tree-structure


【解决方案1】:

经过一番搜索,发现了一个名为 deepdashlodash 库扩展,它具有深度过滤,并且效果很好。

您将拥有 2 个新的依赖项,但我认为它会满足您的目的。 查看有关如何安装它们的文档here

在这里你可以在sn-p中看到日志中的结果。我也做了一个沙盒here

这是一个 id 列表,一个或多个。

如果您只需要一个值,请更改条件。 return _.indexOf(idList, value.id) !== -1;return id===value.id; 其中id 是您的id 变量

此外,在查看 Tabulator 的文档后,它只有一级过滤,即使您编写自己的自定义过滤器也无济于事,因为它需要一个布尔值来呈现行与否。但是只针对第一级,所以如果父级不是你寻找的子级会被忽略。您唯一的选择是过滤制表符之外的数据。

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>

【讨论】:

    【解决方案2】:

    这是一个递归函数,它将找到匹配条件的父级和/或子级。

    在此示例中,如果子项匹配,则始终显示父项 - 即使父项本身不匹配 - 但您可以通过调整 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'});
    

    【讨论】:

      猜你喜欢
      • 2014-07-04
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-27
      • 2019-12-04
      • 2023-02-21
      • 1970-01-01
      相关资源
      最近更新 更多