【问题标题】:Angular filter and limitTo not working as expected角度过滤器和 limitTo 无法按预期工作
【发布时间】:2016-08-04 12:39:18
【问题描述】:

我是 angular.js 的新手,我看到了一些我不喜欢的东西。当我同时过滤和限制数据时,似乎限制会影响过滤器,并且无法在原始数组源中搜索。我错过了什么吗?

更新: 事情是我正在尝试创建一个带有分页、过滤器和其他一些东西的简单数据表指令,但这让我发疯。我已经看到了答案和 cmets,我想知道我试图达到的程序是否错误,但是不,从逻辑上讲,限制一定不会影响过滤器(我认为是这样),因为也许在某些时候你'需要在整个源头中搜索,而不是限制部分,它们应该是分开的行为。这不是我在主要数据表框架中看到的默认行为吗?

这是一个描述问题的示例:

angular.module('ngRepeat', ['ngAnimate']).controller('repeatController', function($scope) {
        $scope.q="john"
        $scope.friends = [
          {name:'John', age:25, gender:'boy'},
          {name:'Jessie', age:30, gender:'girl'},
          {name:'Johanna', age:28, gender:'girl'},
          {name:'Joy', age:15, gender:'girl'},
          {name:'Mary', age:28, gender:'girl'},
          {name:'Peter', age:95, gender:'boy'},
          {name:'Sebastian', age:50, gender:'boy'},
          {name:'Erika', age:27, gender:'girl'},
          {name:'Patrick', age:40, gender:'boy'},
          {name:'Samantha', age:60, gender:'girl'}
        ];
      });
.example-animate-container {
        background:white;
        border:1px solid black;
        list-style:none;
        margin:0;
        padding:0 10px;
      }

      .animate-repeat {
        line-height:30px;
        list-style:none;
        box-sizing:border-box;
      }

      .animate-repeat.ng-move,
      .animate-repeat.ng-enter,
      .animate-repeat.ng-leave {
        transition:all linear 0.5s;
      }

      .animate-repeat.ng-leave.ng-leave-active,
      .animate-repeat.ng-move,
      .animate-repeat.ng-enter {
        opacity:0;
        max-height:0;
      }

      .animate-repeat.ng-leave,
      .animate-repeat.ng-move.ng-move-active,
      .animate-repeat.ng-enter.ng-enter-active {
        opacity:1;
        max-height:30px;
      }
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-animate.min.js"></script>
<div ng-app="ngRepeat" ng-controller="repeatController">
The flollowing example shows when you filter and limit the data at the same time, you can not filter the items before the current position.
<br/>
<b>position</b> : 5<br/>
<b>limitTo</b> : 5<br/>
<b>filter</b> : { '$' : '{{q}}' }<br/>
        I have {{friends.length}} friends. They are:
        <input type="search" value="john" ng-model="q" placeholder="filter friends..." aria-label="filter friends" />
        <ul class="example-animate-container">
          <li class="animate-repeat" ng-repeat="friend in friends | filter:q | limitTo : 5 : 5 as result track by $index">
            [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
          </li>
          <li class="animate-repeat" ng-if="results.length == 0">
            <strong>No results found...</strong>
          </li>
        </ul>
<br/>As you can see there's no results.
      </div>

【问题讨论】:

  • 删除limitTo过滤器的第二个参数,它应该可以工作。
  • 请阅读更新部分
  • “从逻辑上讲,限制不能影响过滤器”。不,当然会影响。

标签: javascript angularjs angularjs-ng-repeat angularjs-filter angularjs-limitto


【解决方案1】:

您遇到问题是因为您的 limitTo 限制了 5 个项目,从索引 5 开始,当您搜索时,很可能不会有 5 个项目,尤其是在提供的数据情况下。

改变

limitTo : 5 : 5 track by $index

limitTo : 5 track by $index

limitTo : 5 : 0 track by $index // 0 = Index at which to begin limitation

【讨论】:

  • “你的 limitTo 是错误的”。好吧,这没有错,只是没有按他的预期工作.. 但它是limitTo 的有效用法。
  • @PedroMora,“从逻辑上讲,限制不能影响过滤器”就是这种情况,您遇到的问题是您从索引 5 限制为 5。这意味着,如果您搜索“女孩'你得到六个结果,但你从索引 5 限制为五个,因此它只显示一个结果
  • 那么,我是否必须创建自己的装饰器???,伙计,在我得到这部分之前,我对 angular 很满意。这是我在主要数据表框架中看到的默认行为
  • 不,使用 limitTo : 5 track by $indexlimitTo : 5 : 0 track by $index,这将过滤您的列表,并限制索引 0 - 5 的结果
  • @PedroMora,因为您刚刚开始阅读文档总是很好。 docs.angularjs.org/api/ng/filter/limitTo
【解决方案2】:

我找到了使用这个的结果

ng-repeat="friend in friends | filter:q | limitTo : 5 as results track by $index"

【讨论】:

  • 请在数据表的分页行为上下文中设置自己,无论您是哪个页面,如果您过滤数据表,它会返回匹配项。
【解决方案3】:

遵循 DataTables.net 的理念,当您开始过滤数据时,它会返回到第一页。我希望它可以帮助别人

angular.module('ngRepeat', ['ngAnimate']).controller('repeatController', function($scope) {
        $scope.position=5;
        $scope.resetPagination = function(){
          if(this.position !== 0) this.position = 0;
        }
        $scope.friends = [
          {name:'John', age:25, gender:'boy'},
          {name:'Jessie', age:30, gender:'girl'},
          {name:'Johanna', age:28, gender:'girl'},
          {name:'Joy', age:15, gender:'girl'},
          {name:'Mary', age:28, gender:'girl'},
          {name:'Peter', age:95, gender:'boy'},
          {name:'Sebastian', age:50, gender:'boy'},
          {name:'Erika', age:27, gender:'girl'},
          {name:'Patrick', age:40, gender:'boy'},
          {name:'Samantha', age:60, gender:'girl'}
        ];
      });
.example-animate-container {
        background:white;
        border:1px solid black;
        list-style:none;
        margin:0;
        padding:0 10px;
      }

      .animate-repeat {
        line-height:30px;
        list-style:none;
        box-sizing:border-box;
      }

      .animate-repeat.ng-move,
      .animate-repeat.ng-enter,
      .animate-repeat.ng-leave {
        transition:all linear 0.5s;
      }

      .animate-repeat.ng-leave.ng-leave-active,
      .animate-repeat.ng-move,
      .animate-repeat.ng-enter {
        opacity:0;
        max-height:0;
      }

      .animate-repeat.ng-leave,
      .animate-repeat.ng-move.ng-move-active,
      .animate-repeat.ng-enter.ng-enter-active {
        opacity:1;
        max-height:30px;
      }
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-animate.min.js"></script>
<div ng-app="ngRepeat" ng-controller="repeatController">
The flollowing example shows when you filter and limit the data at the same time, you can not filter the items before the current position.
<br/>
<b>limitTo</b> : 5<br/>
<b>position</b> : {{position}}<br/>
<b>filter</b> : { '$' : '{{q}}' }<br/>
        I have {{friends.length}} friends. They are:
        <input type="search" value="john" ng-model="q" placeholder="filter friends..." aria-label="filter friends" ng-change="resetPagination()"/>
        <ul class="example-animate-container">
          <li class="animate-repeat" ng-repeat="friend in friends | filter:q | limitTo : 5 : position as results track by $index">
            [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
          </li>
          <li class="animate-repeat" ng-if="results.length == 0">
            <strong>No results found...</strong>
          </li>
        </ul>
<br/>As you can see there's results.
      </div>

【讨论】:

    【解决方案4】:

    这可能对你有帮助..这是分页

    <html>
    <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-animate.min.js"></script>
    <script>
        var app=angular.module('ngRepeat', ['ngAnimate']);
        app.controller('repeatController', function($scope) {
        $scope.q="john";
        $scope.currentPage = 0;
        $scope.pageSize = 5;
        $scope.numberOfPages=function(){
            return Math.ceil($scope.friends.length/$scope.pageSize);                
        }
        $scope.friends = [
          {name:'John', age:25, gender:'boy'},
          {name:'Jessie', age:30, gender:'girl'},
          {name:'Johanna', age:28, gender:'girl'},
          {name:'Joy', age:15, gender:'girl'},
          {name:'Mary', age:28, gender:'girl'},
          {name:'Peter', age:95, gender:'boy'},
          {name:'Sebastian', age:50, gender:'boy'},
          {name:'Erika', age:27, gender:'girl'},
          {name:'Patrick', age:40, gender:'boy'},
          {name:'Samantha', age:60, gender:'girl'}
        ];
      });
      app.filter('startFrom', function() {
        return function(input, start) {
            start = +start; //parse to int
            return input.slice(start);
        }
    });
    </script>
    
    
    <style>
        .example-animate-container {
            background: white;
            border: 1px solid black;
            list-style: none;
            margin: 0;
            padding: 0 10px;
        }
    
        .animate-repeat {
            line-height: 30px;
            list-style: none;
            box-sizing: border-box;
        }
    
        .animate-repeat.ng-move,
        .animate-repeat.ng-enter,
        .animate-repeat.ng-leave {
            transition: all linear 0.5s;
        }
    
        .animate-repeat.ng-leave.ng-leave-active,
        .animate-repeat.ng-move,
        .animate-repeat.ng-enter {
            opacity: 0;
            max-height: 0;
        }
    
        .animate-repeat.ng-leave,
        .animate-repeat.ng-move.ng-move-active,
        .animate-repeat.ng-enter.ng-enter-active {
            opacity: 1;
            max-height: 30px;
        }
    </style>
    

    <div ng-app="ngRepeat" ng-controller="repeatController">
        The flollowing example shows when you filter and limit the data at the same time, you can not filter the items before the
        current position.
        <br/>
        <b>position</b> : 5<br/>
        <b>limitTo</b> : 5<br/>
        <b>filter</b> : { '$' : '{{q}}' }<br/> I have {{friends.length}} friends. They are:
        <input type="search" value="john" ng-model="q" placeholder="filter friends..." aria-label="filter friends" />
        <ul class="example-animate-container">
            <li class="animate-repeat" ng-repeat="friend in friends | filter:q | startFrom:currentPage*pageSize | limitTo:pageSize as results track by $index">
                [{{$index + 1}}] {{friend.name}} who is {{friend.age}} years old.
            </li>
            <li class="animate-repeat" ng-if="results.length == 0">
                <strong>No results found...</strong>
            </li>
        </ul>
        <button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1">
        Previous
    </button>
    {{currentPage+1}}/{{numberOfPages()}}
    <button ng-disabled="currentPage >= friends.length/pageSize-1" ng-click="currentPage=currentPage+1;">
        Next
    </button>
    </div>
    

    【讨论】:

    • 还是不行,如果你从控制器中删除$scope.q = "john"然后过滤数据,问题和我的一样。
    猜你喜欢
    • 1970-01-01
    • 2011-05-22
    • 2019-02-06
    • 1970-01-01
    • 1970-01-01
    • 2022-11-05
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多