JavaScript中的slice函数不适用于分页

slice function in JavaScript not working for pagination

本文关键字:适用于 分页 不适用 函数 中的 slice JavaScript      更新时间:2023-09-26

我正在使用Angularjs做一个Todo应用程序。我试着使用分页,每页只显示5个todo。我可以添加分页,但是slice函数对todos列表不起作用。

它说slice函数未定义。我明白了它行为不明确的原因。这是因为todo列表不在作用域中,我需要以某种方式将todo列表带出来,以便下一个函数可以使用它。但如果没有成功,我可以让它成为可能。

这是我的控制器代码:

todoApp.controller('mainController', ['$scope', '$filter', 'Todos', function($scope, $filter, Todos) {
    $scope.formData = {};
    $scope.loading = true;
    $scope.count = 0;
    $scope.filteredTodos = [];   
    $scope.currentPage = 1;
    $scope.numPerPage = 5;
    $scope.maxSize = 5;
    // GET =====================================================================
    // when landing on the page, get all todos and show them
    // use the service to get all the todos
    //$scope.todos = [];
    Todos.get()
        .success(function(data) {
            $scope.todos = data;
            // for(var i = 0; i < data.length; i++) {
                //$scope.todos.push(data[i]);
            //}
            $scope.loading = false;
            angular.forEach($scope.todos, function(todo){
                todo.formattedCreatedOn = $filter('date')(new Date(todo.createdOn),'MMM dd, yyyy  -  hh:mm a');
            });
        });
     $scope.$watch('currentPage + numPerPage', function() {
        var begin = (($scope.currentPage - 1) * $scope.numPerPage);
        var end = begin + $scope.numPerPage;
        $scope.filteredTodos = $scope.todos.slice(begin, end);
    });
}]);

$scope.todos,我需要以某种方式将其置于当前范围之外。因此它不适用于function $scope.todos.slice(begin,end)

另一件事是在构建todos列表之前调用$watch函数。这是因为当服务从数据库检索todos时,$watch已经在长度为0的列表上被调用,因此无法进一步处理。

我甚至尝试在这个链接中使用代码。

我认为您应该首先定义$scope.todos(有一个注释行,为什么它被注释掉了?),然后检查边界"begin"answers"end"是否在todos数组的大小内。你可能会收到一些元素,这些元素不能被你的numPerPage分割,所以在任何情况下,你都必须检查结束是否超过了你的数组大小,如果是的话,你必须相应地设置它

$scope.$watch('currentPage + numPerPage', function() {
    var begin = (($scope.currentPage - 1) * $scope.numPerPage);
    var end = begin + $scope.numPerPage;
    if(end>=$scope.todos.length)
      end = $scope.todos.length-1;
    $scope.filteredTodos = $scope.todos.slice(begin, end);
});

让我知道这是否奏效。

干杯,克里斯托夫

如果您显示Todos的列表,我认为您的模板中有一个ng重复。您可能对limitTo过滤器感兴趣,这是一种出于显示目的过滤数据的首选方式:

https://docs.angularjs.org/api/ng/filter/limitTo

示例:

angular.module('myApp',[]).controller('TodosController',
function TodosController($scope) {
 $scope.todos = [
  {name:"todo1"},
  {name:"todo2"},
  {name:"todo3"},
  {name:"todo4"},
  {name:"todo5"},
  {name:"todo6"},
  {name:"todo7"}
 ];
  
 /* Rows per page */
 $scope.limit = 3;
 /* We start displaying at item 0 */
 $scope.begin = 0;
}
                                      
);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="myApp" ng-controller="TodosController">
  
 todos (page {{begin/limit}}):
 <ul>
   <li ng-repeat="todo in todos | limitTo:limit : begin">{{todo}}</li>
 </ul>
 <button ng-click="begin = 0">&lt;&lt;</button>
 <button ng-click="begin = begin>=limit ? begin - limit:0">&lt; previous page</button>
 <button ng-click="begin = begin + limit">next page &gt; </button>
</div>

我添加了以下代码:

todoApp.filter('limitFromTo', function(){
    return function(input, from, to){
        return (input != undefined)? input.slice(from, to) : '';
    }
});

并在这里使用了这个过滤器:

ng-repeat="todo in todos | limitFromTo:(currentPage-1)*itemsPerPage:(currentPage*itemsPerPage)"

我没有使用使用使用itemsPerPage(currentPage-1)*itemsPerPage等参数的limitTo函数,而是使用了limitFromTo,这是我自己的过滤器,它将在数组中有两个偏移量,就像如果currentPage是1,那么它将显示0-5、6-10等的记录。limitTo过滤器有一些参数,如要显示多少条记录从哪个索引或偏移,这不是我想要的,因此根据我的需要使用了limitFromTo。它奏效了。

尝试将$scope.$watch放入.success回调:

Todos.get()
    .success(function(data) {
        $scope.$watch('currentPage + numPerPage', function() {
          var begin = (($scope.currentPage - 1) * $scope.numPerPage);
          var end = begin + $scope.numPerPage;
          $scope.filteredTodos = data.slice(begin, end);
        });
    });
});