通过将$resource查询数组添加到AngularJS中另一个数组的底部来进行分页加载

Pagination loading by adding a $resource queried array to the bottom of another in AngularJS

本文关键字:数组 底部 另一个 加载 分页 AngularJS resource 查询 添加      更新时间:2023-09-26

我正在尝试为我的Angular应用程序设置加载,这样当有人转到第2页时,第3页将在后台加载。

我使用$resource来用Post.query()查询PostsPost.query({page: 1})获取ID为0-9的post记录的数组。

我实际的Post控制器接受指定页面的参数:posts.json?page=1,其中每个页面有10个帖子。

所以基本上我想在加载时查询第1页和第2页,然后将它们连接为:

$scope.visiblePosts。当用户在第2页时,我希望在后台加载第3页,并将第3页与$scope.visiblePosts连接起来。

对于分页,我使用以下代码:

视图:

<div ng-repeat="post in filtered = visiblePosts |
 startFrom:(currentPage-1)*pageSize | limitTo:pageSize | orderBy:order:true">

应用程序:

app.filter("startFrom", function() {
  return function(input, start) {
    if (input) {
      start = +start;
      return input.slice(start);
    }
    return [];
  };
});

控制器:

$scope.currentPage = 1;
$scope.pageSize = 10;
$scope.noOfPages = Math.ceil($scope.posts.length / $scope.pageSize);
$scope.noPrev = function() {
  return $scope.currentPage === 1;
};
$scope.noNext = function() {
  return $scope.currentPage === $scope.noOfPages;
};
$scope.prevPage = function() {
  return $scope.setPage($scope.currentPage - 1);
};
$scope.nextPage = function() {
  return $scope.setPage($scope.currentPage + 1);
};
$scope.setPage = function(pageNo) {
  return $scope.currentPage = pageNo;
};
$scope.filter = function() {
  return window.setTimeout((function() {
    return $scope.noOfPages = Math.ceil($scope.filtered.length / $scope.pageSize);
  }), 10);
};
$scope.$watch("currentPage", $scope.setPage);

我们非常感谢您的任何帮助,但似乎没有任何效果。我已经尝试过concat()和其他一些东西。

首先,永远不要在Angular摘要循环之外修改您的范围。忘记setTimeoutsetInterval。相反,使用$timeout$interval内置服务。在您的情况下,您应该尝试$evalAsync:AngularJS:$evalAsync vs$timeout

此外,$scope.$watch("currentPage", $scope.setPage)对我来说毫无意义。

最后,关键是:每次导航到下一页时,控制器(以及作用域)都会被实例化,因此您不能将数据保留在不同页面的作用域中。

与控制器不同,服务是单一的,只实例化一次,从不销毁。

您应该创建一个服务来保存已经加载的帖子并预加载下一页。您的控制器应该只向该服务询问它需要显示的页面。

这种方法的额外好处是您不再需要过滤器。

您也可以使用$cacheFactory中的缓存来保存数据,或者只使用$resource服务的cache选项。然后,您只需在显示当前页面后预加载下一个页面,因此下次将立即从缓存中加载。

示例:

function MyController($scope, $resource) {
    var res = $resource("/posts.json", {}, {
        query: {
            method: 'GET',
            isArray: true,
            // enable caching:
            cache: true
        }
    });
    $scope.currentPage = 1;
    $scope.$watch("currentPage", function() {
        $scope.posts = res.query({
            page: $scope.currentPage
        });
        // precache the next page:
        res.query({
            page: $scope.currentPage + 1    
        });
    });
}

<div ng-repeat="post in posts">