【问题标题】:AngularJS dirPagination Select All Visible RowsAngularJS dirPagination 选择所有可见行
【发布时间】:2015-09-20 09:22:00
【问题描述】:

我正在使用 Angular 和 dirPagination 指令构建一个 CRUD 数据管理项目,并且需要有一个“全选”复选框来选择所有可见/不使用/使用 jQuery 的行。

我从这个开始 - 注意 - 我正在攀登 Angular 学习曲线,并且知道其中的部分/全部可能不是“Angular 方式”,但我也不想开始摆弄(没有双关语) dirPagination 的胆量,因此 dirPagination 指令:

 <tr dir-paginate-start="item in items|filter:filterFunction()|orderBy:sortPredicate:reverse| itemsPerPage: rowsPerPage">

和单独的行复选框

<input type="checkbox" class="rowSelector" ng-model="item.isSelected"  ng-change="rowSelect($index, $event)"/> status: {{item.isSelected}}

以及相关的模型元素:

$scope.items = [] //subsequently filled
$scope.rowsPerPage = 5;
$scope.rowSelect = function (ix, $event) {
           var checked = (typeof $event == 'undefined') ? false : true;
           if (!checked) { $scope.masterCheck = false; }
           var rpp = $scope.rowsPerPage;
           var p = $scope.__default__currentPage;  //dirPagination's current page
           var start = ((Math.max(0, p - 1) * rpp));
           $scope.items[start + ix].isSelected = checked;
       };

按预期工作。选中/取消选中一行,模型中的 {{item.isSelected}} 值会更新并显示在复选框旁边。

然后我添加了这个 /outside/ 的 dirPagination 重复块:

<input type="checkbox" id="masterCheckbox" ng-model="masterCheck" ng-click="checkAll()" />

以及模型中的相关功能:

 $scope.masterCheck = false;
 $scope.checkAll = function () {
           var rpp = $scope.rowsPerPage;
           var p = $scope.__default__currentPage;          //dirPagination's current page
           var start = ((Math.max(0, p - 1) * rpp));
           var checked = $scope.masterCheck == true;
           var rows = document.getElementsByClassName("rowSelector");
           for (var ix = 0; ix < rows.length; ix++) {
               rows[ix].checked = checked;
               $scope.items[start + ix].isSelected = checked;
           }
       }

但是在 checkAll() 函数中检查/取消选中单个行不会反映在每行的 {{item.isSelected}} 显示中。

显式设置单个项目
$scope.items[start + ix].isSelected = checked;

似乎在 checkAll 函数的范围内设置了该项目的“isSelected”属性,但行显示没有改变。

显然我有一些错误,可能误解了范围问题,但此时我被难住了。

非常感谢任何帮助:-)

【问题讨论】:

标签: angularjs checkbox selectall dirpagination


【解决方案1】:

天亮了,终于。

checkAll() 试图通过使用 dir-paginate 的 __default__currentPage 和 Angular 的行 $index 计算其位置来访问每一行。

当然这不起作用,因为 dir-paginate 持有的 items[] 集合已经过过滤和排序,所以当 items[] 确实被检查时 (item.isSelected = true) 选定的项目/行是生活在不可见的页面上。即 - 我们选择了错误的索引。

一个解决方案由以下组成 -

主复选框

<input type="checkbox" id="masterCheckbox" ng-model="masterCheck" ng-click="checkAll()" />

行复选框(注意函数调用)

<input type="checkbox" class="rowSelector" value="{{sourceIndex('senId',item.senId)}}" ng-model="item.isSelected" ng-click="rowSelect(this)" />

dir-paginate 指令控制标签

 <dir-pagination-controls on-page-change="onPageChange(newPageNumber)" max-size="15" direction-links="true" boundary-links="true" pagination-id="" template-url=""></dir-pagination-controls>

以及相关的 $scope 值和函数:

       $scope.items = [];
       $scope.masterCheck = false;
       $scope.onPageChange = function (newPageNumber) {
           //clear all selections on page change
           //dir-paginate provides this hook
           $scope.masterCheck = false;
           for (var i in $scope.items) {
               $scope.items[i].isSelected = false;
           }
       }

       $scope.rowSelect = function (item) {
           //if one is unchecked have to turn master off
           if (!item.isSelected) $scope.masterCheck = false;
       }

       $scope.sourceIndex = function (keyName, key) {
           //gets the actual items index for the row key
           //see here http://stackoverflow.com/questions/21631127/find-the-array-index-of-an-object-with-a-specific-key-value-in-underscore
           //for the 'getIndexBy' prototype extension
           var ix = $scope.items.getIndexBy(keyName, key);
           return ix;

       }

       $scope.checkAll = function () {
           //only visible rows 
           var boxes = document.getElementsByClassName("rowSelector");
           for (var bix in boxes) {
               var ix = boxes[bix].value;
               $scope.items[ix].isSelected = $scope.masterCheck;
           }
       }

可能有更好的方法,但虽然效率不高,但它对普通人来说足够好。

$scope.sourceIndex() 函数将实际的源行索引作为其 value= 属性值填充到行复选框中。

checkAll() 函数然后通过“rowSelector”类获取所有可见行,然后遍历那些从复选框值中获取数据索引并设置适当的 item.isSelected。

$scope.onPageChange 在 dir-Paginate 控制指令中指定,并确保当页面更改时,清除所有行选择。

开心开心。

【讨论】:

    【解决方案2】:

    您的变量 masterCheck 在 rowSelect() 中设置为 false,随后在 checkAll() 中您将 checkAll() 设置为 masterCheck,然后用于分配 isSelected

    这一行是错误的:

    var checked = $scope.masterCheck == true;
    

    因为你想翻转 masterCheck 所以它应该是:

    $scope.masterCheck = !$scope.masterCheck;
    

    然后

    .isSelected = $scope.masterCheck;
    

    您从未将 $scope.masterCheck 设置为 true,因此它始终为 false,并且由于您的 isSelected 值依赖于它,因此它们始终为 false。此外,这作为 checkAll/unCheckAll 的功能,使其仅检查对以下内容的所有更改:

    $scope.masterCheck = !$scope.masterCheck;
    var checked = $scope.masterCheck == true;
    

    【讨论】:

    • 谢谢,但如果任何单独的行未被选中,该行只会取消选中“全选”复选框,这是正确的行为。问题是首先选中 Master 复选框不会更改单个行的状态显示。出于好奇,我确实尝试将其删除,但不幸的是没有快乐。
    • No sorry in the line you are looking at var checked 反映了 masterCheck 框被点击后的选中状态。该行所做的只是确定它现在的状态,点击后。然后,我们设置每一行的状态以匹配该状态,无论它是什么。行复选标记设置正确并正确显示。
    猜你喜欢
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多