5

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

2 回答 2

3

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

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

在此处的代码段中,您可以在日志中看到结果。我也在这里做了一个沙箱

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

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

同样在查看 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>

于 2020-04-06T16:24:39.303 回答
0

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

在此示例中,如果子项匹配,则始终显示父项 - 即使父项本身不匹配 - 但您可以通过调整 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() 但那是另一回事。

此处有关动态运算符分配的更多信息: 变量运算符是否可行?

这是处理所有制表符运算符的实现示例:

// 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'});
于 2021-06-27T22:54:51.297 回答