AngularJS:获取过滤后的 ng-repeat 结果计数以更新我的分页
AngularJS: get filtered ng-repeat result count to update my pagination
我的代码解释:
下面是一个简单的 table,其中有一个 ng-repeat
循环遍历 ctrl.persons
,并将结果存储在变量 ctrl.results
中。包含一个过滤器,允许用户使用文本输入搜索结果,sliceResults
是我的 Angular-UI pagination 的自定义过滤器(它根据当前设置确定要显示的结果的偏移量和限制分页的页面)。
<table>
<tr ng-repeat="result in ctrl.results = (ctrl.persons | filter:searchKeywords) | sliceResults: ctrl.paginationOffset : ctrl.paginationLimit">
<td>{{ $index+1 }}</td>
<td>{{ result.firstName }}</td>
<td>{{ result.lastName }}</td>
</tr>
</table>
Results : {{ ctrl.results.length }}
情况:
在代码的末尾,ctrl.results.length
returns 实时结果的数量,并在用户填写文本输入以搜索结果时相应地发生变化。
然而,当结果数量发生变化时,我的分页并没有相应改变,因此显示的页数不正确(例如,它仍然可以显示 3 页,而只有 1 页)。页数基于我的控制器中的一个变量 (this.paginationTotalItems
)。
问题:
如何在我的视图中的结果数量 (ctrl.results.length
) 发生变化时立即更新控制器中的变量 this.paginationTotalItems
? (或者,有什么替代方法可以更新我的分页?)
我试过的:
我远不是AngularJS专家,大家不要笑话我!我试图在 ng-change
中放置一个带有结果计数的函数,但失败了,因为显然它需要 ng-model
而我没有看到它与 ng-repeat
.
一起工作
我还尝试在 ctrl.results
变量上使用 $watch
,但这导致了一个巨大的控制台错误,因为它在 x 次迭代后中止。另外,我宁愿不使用 $watch
,因为我读到它只适用于 $scope
,我宁愿不使用它(我使用 "controller as" 语法)。
在此先感谢,我会接受有助于我解决问题的答案。
您可以在控制器中使用带有 controllerAs 语法的 $watch
。我知道你说过这不是你的首要任务,但我认为这可能是你最好的解决方案。它看起来像这样:
.controller('myCtrl', function () {
var ctrl = this;
...
$scope.$watch(angular.bind(this, function () {
return this.results.length;
}), function (newVal) {
ctrl.paginationTotalItems = //whatever logic you have
});
....
});
编辑:好的,所以我刚刚想到了另一种您不必使用的方法$scope
。它在您的控制器上包含一个函数,并使用 ng-init
调用它,这将更新您的变量(ng-init
将在每次迭代列表更改时触发):
经过大量简化后,您的控制器将如下所示:
function MyCtrl() {
var ctrl = this;
ctrl.paginationTest = 1;
ctrl.persons = [1,2,3,4,5];
ctrl.calcPagination = function () {
ctrl.paginationTest = Math.floor(Math.random() * 10);
}
}
而 HTML 将是:
<table>
<input ng-model="searchKeywords"/>
<tr ng-repeat="result in ctrl.results = (ctrl.persons | filter:searchKeywords)" ng-init="ctrl.calcPagination()">
<td>{{ result }}</td>
<td>{{ctrl.paginationTest}}</td>
</tr>
</table>
这里有一个 Fiddle,看一下第二列,它会随着输入元素的每次变化而变化。在您的情况下,您只需重新计算 ctrl.paginationTotalItems
.
我知道这个问题已经得到解答,但我想分享我的经验。
我在使用@Omri Aharon 提出的 ng-init
时遇到了一些问题,因为每次我更改文本输入中的值时它都没有调用函数,我解决了它只是删除 ng-init
来自 <tr>
并将 ng-change="ctrl.calcPagination()"
添加到输入中。
HTML 代码如下:
<tbody>
<div class="input-group">
<span class="input-group-addon glyphicon glyphicon-search" aria-hidden="true"></span>
<input type="text" class="form-control" placeholder="Filter..." ng-model="ctrl.filterName" ng-change="ctrl.calcPagination()">
</div>
<tr ng-repeat="item in ctrl.list | filter: ctrl.filterName | orderBy: ctrl.sortType:ctrl.sortReverse | clientPaginator:ctrl.currentPage:ctrl.itemsPerPage">
<td>{{item.property}}</td>
</tr>
</tbody>
以及控制器中的函数:
ctrl.calcPagination = function(){
ctrl.resultCount = $filter('filter')(ctrl.list, ctrl.filterName).length;
}
感谢@Omri Aharon 提供这个简单的解决方案!
我的代码解释:
下面是一个简单的 table,其中有一个 ng-repeat
循环遍历 ctrl.persons
,并将结果存储在变量 ctrl.results
中。包含一个过滤器,允许用户使用文本输入搜索结果,sliceResults
是我的 Angular-UI pagination 的自定义过滤器(它根据当前设置确定要显示的结果的偏移量和限制分页的页面)。
<table>
<tr ng-repeat="result in ctrl.results = (ctrl.persons | filter:searchKeywords) | sliceResults: ctrl.paginationOffset : ctrl.paginationLimit">
<td>{{ $index+1 }}</td>
<td>{{ result.firstName }}</td>
<td>{{ result.lastName }}</td>
</tr>
</table>
Results : {{ ctrl.results.length }}
情况:
在代码的末尾,ctrl.results.length
returns 实时结果的数量,并在用户填写文本输入以搜索结果时相应地发生变化。
然而,当结果数量发生变化时,我的分页并没有相应改变,因此显示的页数不正确(例如,它仍然可以显示 3 页,而只有 1 页)。页数基于我的控制器中的一个变量 (this.paginationTotalItems
)。
问题:
如何在我的视图中的结果数量 (ctrl.results.length
) 发生变化时立即更新控制器中的变量 this.paginationTotalItems
? (或者,有什么替代方法可以更新我的分页?)
我试过的:
我远不是AngularJS专家,大家不要笑话我!我试图在 ng-change
中放置一个带有结果计数的函数,但失败了,因为显然它需要 ng-model
而我没有看到它与 ng-repeat
.
我还尝试在 ctrl.results
变量上使用 $watch
,但这导致了一个巨大的控制台错误,因为它在 x 次迭代后中止。另外,我宁愿不使用 $watch
,因为我读到它只适用于 $scope
,我宁愿不使用它(我使用 "controller as" 语法)。
在此先感谢,我会接受有助于我解决问题的答案。
您可以在控制器中使用带有 controllerAs 语法的 $watch
。我知道你说过这不是你的首要任务,但我认为这可能是你最好的解决方案。它看起来像这样:
.controller('myCtrl', function () {
var ctrl = this;
...
$scope.$watch(angular.bind(this, function () {
return this.results.length;
}), function (newVal) {
ctrl.paginationTotalItems = //whatever logic you have
});
....
});
编辑:好的,所以我刚刚想到了另一种您不必使用的方法$scope
。它在您的控制器上包含一个函数,并使用 ng-init
调用它,这将更新您的变量(ng-init
将在每次迭代列表更改时触发):
经过大量简化后,您的控制器将如下所示:
function MyCtrl() {
var ctrl = this;
ctrl.paginationTest = 1;
ctrl.persons = [1,2,3,4,5];
ctrl.calcPagination = function () {
ctrl.paginationTest = Math.floor(Math.random() * 10);
}
}
而 HTML 将是:
<table>
<input ng-model="searchKeywords"/>
<tr ng-repeat="result in ctrl.results = (ctrl.persons | filter:searchKeywords)" ng-init="ctrl.calcPagination()">
<td>{{ result }}</td>
<td>{{ctrl.paginationTest}}</td>
</tr>
</table>
这里有一个 Fiddle,看一下第二列,它会随着输入元素的每次变化而变化。在您的情况下,您只需重新计算 ctrl.paginationTotalItems
.
我知道这个问题已经得到解答,但我想分享我的经验。
我在使用@Omri Aharon 提出的 ng-init
时遇到了一些问题,因为每次我更改文本输入中的值时它都没有调用函数,我解决了它只是删除 ng-init
来自 <tr>
并将 ng-change="ctrl.calcPagination()"
添加到输入中。
HTML 代码如下:
<tbody>
<div class="input-group">
<span class="input-group-addon glyphicon glyphicon-search" aria-hidden="true"></span>
<input type="text" class="form-control" placeholder="Filter..." ng-model="ctrl.filterName" ng-change="ctrl.calcPagination()">
</div>
<tr ng-repeat="item in ctrl.list | filter: ctrl.filterName | orderBy: ctrl.sortType:ctrl.sortReverse | clientPaginator:ctrl.currentPage:ctrl.itemsPerPage">
<td>{{item.property}}</td>
</tr>
</tbody>
以及控制器中的函数:
ctrl.calcPagination = function(){
ctrl.resultCount = $filter('filter')(ctrl.list, ctrl.filterName).length;
}
感谢@Omri Aharon 提供这个简单的解决方案!