【问题标题】:AngularJS: get filtered ng-repeat result count to update my paginationAngularJS:获取过滤的 ng-repeat 结果计数以更新我的分页
【发布时间】:2015-06-22 14:19:24
【问题描述】:

我的代码解释:

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

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

问题:

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

我尝试了什么:

我远不是 AngularJS 专家,所以不要笑我!我试图在ng-change 中添加一个函数并计算结果计数,但失败了,因为它显然需要ng-model,而我看不到与ng-repeat 一起使用。

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

提前致谢,我会接受有助于我解决问题的答案。

【问题讨论】:

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


    【解决方案1】:

    您可以在控制器中使用带有 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,看看第 2 列,会发现它在输入元素的每次更改后都会发生变化。在您的情况下,您只需重新计算 ctrl.paginationTotalItems

    【讨论】:

    • 感谢您的回答。是的,您的$watch 似乎工作得很好!我一定是搞砸了我的。但是,如果没有$watch,还有没有办法实现这一点?我的控制器中没有包含$scope(我可以添加它,但我宁愿不添加)。
    • @Nic 实际上,可能有......只是想到了另一种可能适合您的方式。让我稍后更新答案。
    • @Nic 更新了答案。
    【解决方案2】:

    我知道这个问题已经得到解答,但我想分享我的经验。

    我在使用@Omri Aharon 提出的ng-init 时遇到了一些问题,因为每次我更改文本输入中的值时它都没有调用函数,我解决了它只是从&lt;tr&gt; 中删除ng-init 和在输入中添加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 提供这个简单的解决方案!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 2018-01-28
      • 2014-06-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多