Angularjs 如何在ng网格分组中设置复选框

Angularjs 如何在ng网格分组中设置复选框,angularjs,checkbox,ng-grid,Angularjs,Checkbox,Ng Grid,是否可以在ng网格分组标题中设置复选框? 单击该分组复选框时,应选中该特定组下所有行的复选框。 其他组行应保持未选中状态 现在,当我的gridOptions如下所示时,我会看到所有行的复选框,以及表格标题中的复选框。当拖动列标题以将其用于分组时,分组行标题没有复选框。 有人能帮忙吗 $scope.gridOptions = { data: 'myData', showGroupPanel: true, showSelectionCheckbox: true, jq

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

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

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

要实现此目标,首先必须覆盖默认的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>"  
};

我在拼命寻找同一个问题的答案时发现了这个问题,虽然为我指明了正确的方向,但它并没有如预期的那样奏效*

在玩了几天ngRow和NGAGGRAGATE对象的内容之后,我最终得出了以下结论

我的aggregateTemplate与Eric的非常相似,但有一些区别。首先,我在(
span class=“{{row.aggClass()}}>”
)中添加了展开/折叠图标。我还将
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>';
相反,在这个版本中,我们称之为:

row.selectionProvider.setSelection (row, group.status.isChecked)
因为它采用的是行本身而不是索引,所以不管索引有多复杂,它都可以工作

此版本也适用于嵌套组。例如,当您按年龄分组时,City>Age,您得到一个包含53组的明尼苏达州组,单击53组的组头将选择居住在Minesota的所有53岁的人,而不是其他城市的53岁的人或其他年龄的明尼苏达州人。另一方面,单击明尼苏达州的组标题将选择明尼苏达州的所有人,并选中每个子组的组标题复选框。同样,如果明尼苏达州组中只有53岁的人,那么单击53复选框也会勾选明尼苏达复选框

这让我想到了最后的变化。对于每个组都有一个观察者(我通常不喜欢观察者并试图避免他们,但有时他们是一个必要的恶魔),我们跟踪每个组内的选择,并在选择每一行时自动勾选组标题中的框。就像网格顶部的“全选”复选框一样

下面是代码:

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字段映射到其模型中的正确行。我认为这是因为行被重新排列以进行分组和排序,而内部映射没有保持不变

row.selectionProvider.setSelection (row, group.status.isChecked)
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;
}