【问题标题】:angular ui-grid selecting all under grouping角度 ui-grid 在分组下选择所有
【发布时间】:2023-03-15 16:49:01
【问题描述】:

https://jsfiddle.net/4byyuqtc/1/

选择分组行时,我希望让UI-Grid在分组下选择所有“孩子”。在这种情况下,Kit Kat(1)、Mr. Goodbar(1)、Krackel(2) 并最终选择实际记录(非粗线)。人们会期望,当在一个分组中选择一个父级时,它的所有子级也会被选中。

当前在数据中选择1分组(非粗体线)中的实际记录上方时,它确实选择了以下代码的那些实际记录:

$scope.gridApi.selection.on.rowSelectionChanged($scope, function (rowChanged) {
    console.log(rowChanged.treeLevel);
    if (typeof (rowChanged.treeLevel) !== 'undefined' && rowChanged.treeLevel > -1) {
        // this is a group header
        children = $scope.gridApi.treeBase.getRowChildren(rowChanged);
        console.log(children);
        children.forEach(function (child) {
            if (rowChanged.isSelected) {
                $scope.gridApi.selection.selectRow(child.entity);
            } else {
                $scope.gridApi.selection.unSelectRow(child.entity);
            }
        });
    }
});

此时我对 ui-grid 的经验还不够,无法弄清楚如何循环遍历所选行的子行并选择所有子行。

[编辑]

使用下面的 Paul 代码,它不会选择分组,但更接近。此屏幕截图是我选择第一个 337 记录。请注意,它选择了该记录和所有最低的子记录(这很好,因为最终这些记录才是重要的),但在视觉上,分组记录(MFG 和 Item Desc 组)没有被选择,需要像用户那样选择曾经打开最低的数据记录,因此他们需要查看所选组。

【问题讨论】:

    标签: angular-ui-grid


    【解决方案1】:

    我检查了文档,我认为没有任何公开的 API 方法。您可以递归地选择/取消选择行作为解决方案。请尝试以下示例。

    $scope.gridApi.selection.on.rowSelectionChanged($scope, function (rowChanged) {
                        console.log(rowChanged.treeLevel);
                        if (typeof(rowChanged.treeLevel) !== 'undefined' && rowChanged.treeLevel > -1) {
                            var children = $scope.gridApi.treeBase.getRowChildren(rowChanged);
                            selectChildren(children, rowChanged.isSelected);
                        }
                    });
    
    function selectChildren(gridRows, selected) {
                            if (gridRows && gridRows.length > 0) {
                                gridRows.forEach(function (child) {
                                    if (selected) {
                                        $scope.gridApi.selection.selectRow(child.entity);
                                    } else {
                                        $scope.gridApi.selection.unSelectRow(child.entity);
                                    }
    
                                    var children = $scope.gridApi.treeBase.getRowChildren(child);
                                    selectChildren(children, selected); //recursively select/de-select children
                                });
                            }
                        }
    

    这是一个正常工作的 Plunkr:http://plnkr.co/edit/XsoEUncuigj9Cad1vP5E?p=preview

    处理自动取消选择有点棘手,尽管 api 似乎不能很好地处理。

    更新

    因此,我检查了您共享的 jsFiddle,并通过稍微调整使其正常工作。

    我将 selectionHandler 修改为以下内容:

    onRegisterApi: function(gridApi) {
      $scope.gridApi = gridApi;
      $scope.gridApi.selection.on.rowSelectionChanged($scope, function(rowChanged) {
        if (rowChanged.treeNode.parentRow) { //Added this parent row selection
            rowChanged.treeNode.parentRow.setSelected(rowChanged.isSelected);
        }
        console.log(rowChanged.treeLevel);
        if (typeof(rowChanged.treeLevel) !== 'undefined' && rowChanged.treeLevel > -1) {
          var children = $scope.gridApi.treeBase.getRowChildren(rowChanged);
          selectChildren(children, rowChanged.isSelected);
        }
      });
    

    请查看您的代码的这个分支:https://jsfiddle.net/1eg5v77w/

    这样做的缺点是,如果您选择低级别条目(没有子条目),它仍会选择其父条目。如果您真的希望它也能正常工作,您将不得不访问 DOM 并进行一些丑陋的检查。

    $scope.gridApi.selection.on.rowSelectionChanged($scope, function(rowChanged, $event) {
            var wasHeaderRowClicked = true;
            try {   //This can be written more beautifully if you used jQuery. But I would still be against it as it relies on the class of the ui-grid never changing when you update your ui-grid version.
              wasHeaderRowClicked = $event
              .srcElement
              .parentElement
              .parentElement
              .parentElement
              .previousElementSibling
              .firstChild
              .firstChild
              .firstChild
              .getAttribute('class') === 'ui-grid-icon-minus-squared';
            } catch(err) { console.log('Couldnt determine if header row was clicked'); }
            if (rowChanged.treeNode.parentRow && wasHeaderRowClicked) {
                rowChanged.treeNode.parentRow.setSelected(rowChanged.isSelected);
            }
            console.log(rowChanged.treeLevel);
            if (typeof(rowChanged.treeLevel) !== 'undefined' && rowChanged.treeLevel > -1) {
              var children = $scope.gridApi.treeBase.getRowChildren(rowChanged);
              selectChildren(children, rowChanged.isSelected);
            }
          });
    

    这里是小提琴:https://jsfiddle.net/Lf8p7Luk/1/

    我还想补充一下,感谢post,根据UI-Grid documentation无法编辑组标题行,如果使用选择功能,则无法选择。但是,它们可以被导出。

    因此,很难让它发挥作用是故意的,因为它不是预期的设计。我的建议是更改您的逻辑以使用树级别或绕过选择逻辑,因为即使我的分叉当前正在选择所有内容,您很可能会遇到其他问题。例如:当您单击另一个组标题时,我无法在网格中自动取消选择。

    【讨论】:

    • 所以我尝试了代码,但它不起作用。我注意到的一个区别是您在数据中添加了这个 $$treeLevel 设置。我没有那个,我也不知道。可以以用户在运行时决定的任何方式对数据进行分组。所以我认为这可能会弄乱我没有/使用它的代码。我需要这个分组不可知论者。
    • $$treeLevel 仅在演示中存在。实际的选择事件处理程序不使用该属性。
    • 所以在我的应用程序中,您的代码正确选择了最低级别,但它没有选择任何需要选择的分组行。我注意到它在日志中显示它正在选择一些(最低级别),但随后我也打印了几次“未定义”,这必须是分组行。
    • 我会做一个更符合我的设置的 plunker。
    • 在制作 plunker 时遇到问题。当我尝试保存时,我不断获得权限被拒绝。当我在上面应用您的代码时,我用一张图片和描述更新了我的原始帖子。
    【解决方案2】:

    如果您仍然有问题,请查看此..

    https://github.com/angular-ui/ui-grid/issues/3911

    【讨论】:

    • 其中一个例子很有效,但只有当我有 2 个级别时。我的分组是按 3 个级别进行的,在 3 个级别上根本不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2017-11-08
    • 1970-01-01
    相关资源
    最近更新 更多