【问题标题】:Update pagination in AngularJS after filtering过滤后更新AngularJS中的分页
【发布时间】:2013-04-15 04:08:15
【问题描述】:

我已经实现了分页。 现在我希望在过滤结果后更新分页。

形式:

<input type="text" data-ng-model="search.name" data-ng-change="filter()"/>

名单:

<li data-ng-repeat="data in filtered = (list | filter:search) | filter:search | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">{{data.name}}</li>

分页:

<pagination data-boundary-links="true" data-num-pages="noOfPages" data-current-page="currentPage" max-size="maxSize"></pagination>

控制器:

$scope.filter = function() {
    window.setTimeout(function() { //wait for 'filtered' to be changed
        $scope.noOfPages = Math.ceil($scope.filtered.length/$scope.entryLimit);
        $scope.setPage = function(pageNo) {
            $scope.currentPage = pageNo;
        };
    }, 10);
};

我的问题是,在单击页码或在输入字段中输入下一个字符后,分页才会更新。所以更新晚了一步。

编辑:我将源添加到 jsFiddle:http://jsfiddle.net/eqCWL/2/

【问题讨论】:

    标签: javascript angularjs pagination


    【解决方案1】:

    使用$timeout 代替window.setTimeOut$timeout 被正确包装以在 Angular 中始终如一地工作。

    【讨论】:

      【解决方案2】:

      使用角度$scope.$watch

      $scope.$watch('search', function(term) {
          $scope.filter = function() {
              $scope.noOfPages = Math.ceil($scope.filtered.length/$scope.entryLimit);
          }
      });
      

      来源; http://jsfiddle.net/eqCWL/2/

      演示; http://jsfiddle.net/eqCWL/192/

      【讨论】:

        【解决方案3】:

        你可以简单地使用这个指令来代替:

        https://github.com/michaelbromley/angularUtils/tree/master/src/directives/pagination

        它通过过滤器提供分页,同时保持代码整洁。

        感谢 michaelbromley 的出色代码。

        【讨论】:

          【解决方案4】:

          @abject_error 使用$timeout 的答案确实有效。我根据他的建议编辑了你的小提琴并制作了这个jsFiddle

          警告

          我认为这个解决方案以竞争条件的形式表明了一个更大的问题!

          jsFiddle using filterFilter and $watch

          而那个小提琴就是真正的解决方法。

          这里是解释

          您的竞争条件介于处理search 的更改和$scope.filtered 的可用性之间。

          我认为为了解决这种竞争状况而要消除的罪魁祸首是:

          ng-model="search" ng-change="filter()"
          

          ng-repeat="data in filtered = (list | filter:search)......."
          

          使用ng-change 触发“filter()”来计算noOfPages,但也取决于搜索的变化以创建filtered。这样做可以确保过滤后的列表可能无法及时准备好计算页数,这就是为什么将“filter()”延迟 10 毫秒并超时会给你一种工作程序的错觉。

          您需要一种“观察”search 更改的方法,然后在您可以访问创建$scope.filtered 和计算$scope.noOfPages 的位置过滤列表。全部按顺序进行,没有比赛。

          Angular 就是这样!可以在控制器中使用filter 过滤器作为名称非常糟糕的函数:filterFilter。在Filters Guide - Using filters in controllers and services 中查看此内容

          将其注入控制器。

          function pageCtrl($scope, filterFilter) {
              // ...
          }
          

          $watch 函数中使用它,记录在scopes docs

          $scope.$watch('search', function(term) {  
              // Create filtered 
              $scope.filtered = filterFilter($scope.list, term);  
          
              // Then calculate noOfPages
              $scope.noOfPages = Math.ceil($scope.filtered.length/$scope.entryLimit);  
          })
          

          更改模板以反映我们的新方式。 DOM 过滤器中不再有,或 ng-change

          <input type="text" ng-model="search" placeholder="Search"/>
          

          <li ng-repeat="data in filtered | startFrom:(currentPage-1)*entryLimit | limitTo:entryLimit">
              {{data.name}}
          </li>
          

          【讨论】:

          • 这看起来像一个更好的解决方案,但如果我将 ng-model="search" 更改为 ng-model"search.name" 如下 它似乎坏了。这是什么原因造成的。我问这个是因为我希望能够过滤多个列
          • 将监视表达式也更改为search.name。您可能需要考虑 $watchCollection 是否适合您的情况。允许您查看对象的属性。
          • 我已经弄清楚了 $watch 函数的第三个参数,但我认为 $watchCollection 更好。谢谢你。
          • 我有自己的分页指令,因为我必须跨多个页面实现分页和搜索。在这种情况下,我如何将搜索逻辑添加到我的指令中,因为 ng-repeat 指的是控制器。如果我必须将此逻辑添加到控制器,那么我必须复制粘贴我所有页面的代码。有什么建议吗?
          • 我在同一条船上......我喜欢这个解决方案,但我不确定如何在我的整个应用程序中实现它而不复制/粘贴每个控制器中的代码
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-06-02
          • 1970-01-01
          • 2013-04-16
          • 1970-01-01
          • 2018-04-04
          • 1970-01-01
          • 2015-06-22
          相关资源
          最近更新 更多