如何在ng-grid分组中设置复选框

时间:2013-11-14 23:10:23

标签: angularjs checkbox ng-grid

是否可以在ng-grid分组标题中设置复选框? 单击该分组复选框时,应选择该特定组下的所有行的复选框。 其他组行应保持未选中状态。

现在,当我有如下的gridOptions时,我会看到所有行和表头中的复选框。拖动列标题以将其用于分组时,分组的行标题没有复选框。 有人可以帮忙吗?

$scope.gridOptions = {
    data: 'myData',
    showGroupPanel: true,
    showSelectionCheckbox: true,
    jqueryUITheme: true,
    enableCellSelection: true,
    enableRowSelection: true,
    enableCellEdit: false,
    pinSelectionCheckbox: false,
    selectWithCheckboxOnly: true
};

2 个答案:

答案 0 :(得分:2)

为了实现它,首先要覆盖默认的aggregateTemplate:

$scope.gridOptions = {
  data: 'myData',
  showGroupPanel: true,
  showSelectionCheckbox: true,
  jqueryUITheme: true,
  enableRowSelection: true,
  aggregateTemplate: "<div ng-init=\"initAggregateGroup(row)\" ng-style=\"rowStyle(row)\" style=\"top: 0px; height: 48px; left: 0px; cursor:pointer\" class=\"ngAggregate\">" +
"    <span class=\"ngAggregateText\" ng-click=\"expandGroupChilds($event, row)\">{{row.label CUSTOM_FILTERS}} ({{row.totalChildren()}} {{AggItemsLabel}})</span>" +
"<input class=\"ngSelectionHeader\" type=\"checkbox\" ng-show=\"multiSelect\" ng-checked=\"row.status.isChecked\" ng-model=\"row.status.isChecked\" ng-change=\"toggleGroupSelectedChilds(row)\" /></div>"  
};

然后您可以在控制器中添加这些功能:

$scope.expandAll = function($event){
   $scope.isAllCollapsed = !$scope.isAllCollapsed;
   _.each($scope.ngGridOptions.ngGrid.rowFactory.aggCache, function(row){
     row.toggleExpand();
   });
};

$scope.initAggregateGroup = function(group){
   group.status = {
      isChecked: false
   };
};

$scope.toggleGroupSelectedChilds = function(group){
  _.each(group.children, function(entry){
      $scope.ngGridOptions.selectItem(entry.rowIndex, group.status.isChecked);
  });
};

$scope.expandGroupChilds = function($event, group){
   $event.stopPropagation();
   $event.preventDefault();

   group.toggleExpand();
};

答案 1 :(得分:2)

我在拼命寻找同一问题的答案时发现了这个问题,虽然Eric's answer指出了正确的方向,但它并没有按预期工作*。

这是我在玩了几天ngRow和ngAggregate对象的内容之后最终得到的。

我的aggregateTemplate非常类似于Eric,但有一些差异。首先,我在(span class="{{row.aggClass()}}></span>")中添加了展开/折叠图标。我还将ng-click="expandGroupChildren($event, row)"移至包含div,并将ng-click="$event.stopPropagation()"添加到复选框。这意味着单击任意位置,但复选框将展开/折叠组。最后,我重命名了一些功能。

var aggregateTemplate = '<div ng-init="initAggregateGroup(row)" ng-style="rowStyle(row)" style="top: 0; height: 48px; left: 0; cursor:pointer" class="ngAggregate" ng-click="expandGroupChildren($event, row)">' +
    '<span class="{{row.aggClass()}}"></span>' +
    '<input class="ngSelectionHeader" type="checkbox" ng-show="multiSelect" ng-checked="row.status.isChecked" ng-model="row.status.isChecked" ng-change="setGroupSelection(row)" ng-click="$event.stopPropagation()" />' +
    '<span class="ngAggregateText">{{row.label CUSTOM_FILTERS}} ({{row.totalChildren()}} {{AggItemsLabel}})</span>' +
'</div>';

但功能代码是我真正分歧的地方。

首先,这对我不起作用:

$scope.gridOptions.selectItem(entry.rowIndex, group.status.isChecked)

相反,在这个版本中我们称之为:

row.selectionProvider.setSelection (row, group.status.isChecked)

因为它取自行本身而不是索引,所以无论指数多么纠结,它都能正常工作。

此版本也适用于嵌套组。例如,当您按城市&gt;进行分组时年龄,你得到一个包含 53 组的 Minnesota 组,点击 53 的组头将选择所有53-生活在Minesota的年龄,但不是其他城市的53岁或其他年龄的明尼苏达人。另一方面,单击 Minnesota 的组标题将选择明尼苏达州的每个人,以及每个子组的组头复选框。同样,如果我们 Minnesota 组中有53岁的人,那么点击 53 复选框也会勾选明尼苏达州复选框。

这让我想到了最后的改变。每组观察者(我通常不喜欢观察者并试图避开它们,但有时候它们是必要的邪恶),我们会跟踪每个组中的选择并在每一行中自动勾选组头中的框被选中。就像网格顶部的select-all复选框一样。

所以这是代码:

angular.extend ($scope, {
    initAggregateGroup  : initAggregateGroup,
    expandGroupChildren : expandGroupChildren,
    setGroupSelection   : setGroupSelection
});

function initAggregateGroup (group) {
    group.status = {
        isChecked: getGroupSelection (group)
    };
    $scope.$watch (
        function () {
            return getGroupSelection (group)
        },
        function (isSelected) {
            setGroupSelection (group, isSelected);
        }
    )
}

function expandGroupChildren ($event, group) {
    $event.stopPropagation ();
    $event.preventDefault ();
    group.toggleExpand ();
}

function setGroupSelection (group, isSelected) {
    // Sets the field when called by the watcher (in which case the field needs to be updated)
    // or during recursion (in which case the objects inside aggChildren don't have it set at all)
    if (_.isBoolean (isSelected)) {
        group.status = { isChecked : isSelected }
    }
    // Protects against infinite digest loops caused by the watcher above
    if (group.status.isChecked === getGroupSelection (group)) { return }

    _.forEach (group.children, function (row) {
        // children: ngRow objects that represent actual data rows
        row.selectionProvider.setSelection (row, group.status.isChecked);
    });
    _.forEach (group.aggChildren, function (subGroup) {
        // aggChildren: ngAggregate objects that represent groups
        setGroupSelection (subGroup, group.status.isChecked);
    });
}

function getGroupSelection (group) {
    if (group.children.length > 0) {
        return _.every (group.children, 'selected');
    }
    if (group.aggChildren.length > 0) {
        return _.every (group.aggChildren, getGroupSelection);
    }
    return false;
}

*单击aggregateTemplate中的复选框将从网格中的所有行中选择一个看似随机的行集合(看似随机,因为它在单独的会话中对于相同的数据是一致的)。

我认为问题(至少对我来说在ngGrid 2.0.12中)是ngGrid没有正确地将rowIndex字段映射到其模型中的右行。我认为这是因为行重新排列了分组和排序,内部映射没有跟上。