AngularJS:获取过滤的ng-repeat结果计数以更新我的分页

时间:2015-04-16 09:13:33

标签: javascript angularjs angular-ui-bootstrap mean-stack meanjs

我的代码解释道:

下面是一个简单的表,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实时返回结果数量,并在用户填写文本输入以搜索结果时进行相应更改。

然而,当结果数量发生变化时,我的分页不会相应地改变,因此会显示不正确的页面数量(例如,当只有1页时,它仍然可以显示3页)。页面数量基于我的控制器中的变量(this.paginationTotalItems)。

问题:

在我的视图中,一旦结果量(this.paginationTotalItems)发生变化,如何更新控制器中的变量ctrl.results.length? (或者,有什么替代方法来更新我的分页?)

我尝试了什么:

我远非成为AngularJS专家,所以不要嘲笑我!我尝试在ng-change中添加一个带有结果计数的函数,该函数失败,因为它显然需要ng-model而我看不到它与ng-repeat一起工作。

我还尝试在$watch变量上使用ctrl.results,但这导致了大量的控制台错误,因为它在x次迭代后中止。另外,我宁愿不使用$watch,因为我读它只适用于$scope,我宁愿不使用(我使用“控制器作为”语法)。

在此先感谢,我会接受帮助我解决问题的答案。

2 个答案:

答案 0 :(得分:3)

您可以在控制器中使用带有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

答案 1 :(得分:0)

我知道这个问题已经回答,但我想分享一下我的经验。

我在使用@Omri Aharon提出的ng-init时遇到了一些问题,因为每次我更改文本输入中的值时都没有调用函数,我解决了它只是从<tr>移除ng-change="ctrl.calcPagination()"并在输入中添加<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>

HTML代码如下:

ctrl.calcPagination = function(){
    ctrl.resultCount =  $filter('filter')(ctrl.list, ctrl.filterName).length;
}

控制器中的功能:

public class SmallCalculator {

    public static int getLength(String string){

        int length = 0;

        //length = string.length(); // Uncomment this line and the mocking no longer works... 

        return length;
    }
}

感谢@Omri Aharon提供这个简单的解决方案!