AngularJS 1.6 分页不显示

Posted

技术标签:

【中文标题】AngularJS 1.6 分页不显示【英文标题】:AngularJS 1.6 pagination not displaying 【发布时间】:2018-08-07 11:48:04 【问题描述】:

我是 Angular 的新手,我正在构建 Jason Watmore (http://jasonwatmore.com/post/2016/01/31/angularjs-pagination-example-with-logic-like-google) 之前创建的分页教程。

我已经非常接近让它发挥作用,但我显然错过了一些关键步骤。

我的示例应用程序将退出,获取数据并返回它,但它没有显示在页面上的 div 中,并且分页不起作用(如预期的那样)。

Index.html

<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>

<body>
  <div class="contentWrapper">
     <div data-ng-controller="searchBtnCtrl as vm">
  <h3>Search:</h3>
  <input id="searchQuery" type="text" placeholder="enter your search query here" data-ng-model="searchInput" />

  <button id="searchBtn" data-ng-click="performSearch()">SEARCH</button>

  <div id="searchResults">
    <!-- items being paged -->
    <div ng-repeat="post in vm.posts"><a href='post.title' alt='post.title'>post.title</a><br />post.body</div>

    <!-- pager -->
    <ul ng-if="vm.pager.pages.length" class="pagination">
      <li ng-class="disabled:vm.pager.currentPage === 1">
        <a ng-click="vm.setPage(1)">First</a>
      </li>
      <li ng-class="disabled:vm.pager.currentPage === 1">
        <a ng-click="vm.setPage(vm.pager.currentPage - 1)">Previous</a>
      </li>
      <li ng-repeat="page in vm.pager.pages" ng-class="active:vm.pager.currentPage === page">
        <a ng-click="vm.setPage(page)">page</a>
      </li>
      <li ng-class="disabled:vm.pager.currentPage === vm.pager.totalPages">
        <a ng-click="vm.setPage(vm.pager.currentPage + 1)">Next</a>
      </li>
      <li ng-class="disabled:vm.pager.currentPage === vm.pager.totalPages">
        <a ng-click="vm.setPage(vm.pager.totalPages)">Last</a>
        </li>
      </ul>
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
</body>
</html> 

app.js

(function () 
    'use strict';

    var app = angular
        .module('testApp', [])
        .factory('PagerService', PagerService);

    //controllers
        app.controller('searchBtnCtrl', ['$scope', '$http', 'PagerService', function ($scope, $http, PagerService) 
        $scope.performSearch = function() 
            console.log('clicked');
            $('#searchResults').html('');

            var vm = this;

            $http.get('https://jsonplaceholder.typicode.com/posts').then(function (response) 
                $scope.responseData = response.data;
                console.log($scope.responseData.length);
                console.log($scope.responseData);

                vm.itemsToDisplay = $scope.responseData; // array of items to be paged
                vm.pager = ;
                vm.setPage = setPage;

                initController();

                function initController() 
                    // initialize to page 1
                    vm.setPage(1);
                

                function setPage(page) 
                    if (page < 1 || page > vm.pager.totalPages) 
                        return;
                    

                    // get pager object from service
                    vm.pager = PagerService.GetPager(vm.itemsToDisplay.length, page);

                    // get current page of items
                    vm.items = vm.itemsToDisplay.slice(vm.pager.startIndex, vm.pager.endIndex + 1);
                

            );
        
    ]);

    function PagerService() 
        // service definition
        var service = ;

        service.GetPager = GetPager;

        return service;

        // service implementation
        function GetPager(totalItems, currentPage, pageSize) 
            // default to first page
            currentPage = currentPage || 1;

            // default page size is 10
            pageSize = pageSize || 10;

            // calculate total pages
            var totalPages = Math.ceil(totalItems / pageSize);

            var startPage, endPage;
            if (totalPages <= 10) 
                // less than 10 total pages so show all
                startPage = 1;
                endPage = totalPages;
             else 
                // more than 10 total pages so calculate start and end pages
                if (currentPage <= 6) 
                    startPage = 1;
                    endPage = 10;
                 else if (currentPage + 4 >= totalPages) 
                    startPage = totalPages - 9;
                    endPage = totalPages;
                 else 
                    startPage = currentPage - 5;
                    endPage = currentPage + 4;
                
            

            // calculate start and end item indexes
            var startIndex = (currentPage - 1) * pageSize;
            var endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);

            // create an array of pages to ng-repeat in the pager control
            var pages = _.range(startPage, endPage + 1);

            // return object with all pager properties required by the view
            return 
                totalItems: totalItems,
                currentPage: currentPage,
                pageSize: pageSize,
                totalPages: totalPages,
                startPage: startPage,
                endPage: endPage,
                startIndex: startIndex,
                endIndex: endIndex,
                pages: pages
            ;
        
    



)();

这是项目的代码笔。 对于本例,忽略搜索框,只需按搜索按钮即可激活脚本。

https://codepen.io/code_nick/pen/gvQJLX?editors=1010

还有调试版本。如果您在打开控制台的情况下查看此版本,您会看到它正在计算返回的项目数(好)并将数据作为对象返回(也好),它只是没有显示在页面上(令人讨厌的 #1)和分页不起作用(无赖 #2)。

https://s.codepen.io/code_nick/debug/gvQJLX/PBMNWxowdewr

我认为这可能是范围问题,但由于 Angular 中的范围仍然给我带来问题,也许当 ng-repeat 在 html 中触发时数据不可用?

【问题讨论】:

在 ng-repeat 中,你从哪里得到这个? vm.posts 。你的 JS 中没有这样的对象。 为什么要清除包含 ur ng-repeat 和 pages 的 html? $('#searchResults').html(''); 这样在每次额外的搜索中,它都以一个空的 div 开始。但是分页可能会解决这个问题,所以也许没有必要这样做? ng-repeat 有双向绑定。对象发生变化时会自动更新。 ...当然会的..天啊..我傻了..我仍然在思考Angular的一些概念。谢谢! 【参考方案1】:

有 3 件事是不对的。

    您需要在外部存储控制器的this 引用 performSearch 函数。 您不应该将 searchResults 中的 html 替换为空 您在ng-repeat 中使用vm.posts,但vm.items 持有帖子

通过所有修复,最终代码应如下所示

JS

(function() 
  "use strict";

  var app = angular.module("testApp", []).factory("PagerService", PagerService);

  //controllers
  app.controller("searchBtnCtrl", [
    "$scope",
    "$http",
    "PagerService",
    function($scope, $http, PagerService) 
      var vm = this;
      $scope.performSearch = function() 
        console.log("clicked");
        $(".post").remove();

        $http
          .get("https://jsonplaceholder.typicode.com/posts")
          .then(function(response) 
            $scope.responseData = response.data;
            console.log($scope.responseData.length);
            console.log($scope.responseData);

            vm.itemsToDisplay = $scope.responseData; // array of items to be paged
            vm.pager = ;
            vm.setPage = setPage;

            initController();

            function initController() 
              // initialize to page 1
              vm.setPage(1);
            

            function setPage(page) 
              if (page < 1 || page > vm.pager.totalPages) 
                return;
              

              // get pager object from service
              vm.pager = PagerService.GetPager(vm.itemsToDisplay.length, page);

              // get current page of items
              vm.posts = vm.itemsToDisplay.slice(
                vm.pager.startIndex,
                vm.pager.endIndex + 1
              );
            
          );
      ;
    
  ]);

  function PagerService() 
    // service definition
    var service = ;

    service.GetPager = GetPager;

    return service;

    // service implementation
    function GetPager(totalItems, currentPage, pageSize) 
      // default to first page
      currentPage = currentPage || 1;

      // default page size is 10
      pageSize = pageSize || 10;

      // calculate total pages
      var totalPages = Math.ceil(totalItems / pageSize);

      var startPage, endPage;
      if (totalPages <= 10) 
        // less than 10 total pages so show all
        startPage = 1;
        endPage = totalPages;
       else 
        // more than 10 total pages so calculate start and end pages
        if (currentPage <= 6) 
          startPage = 1;
          endPage = 10;
         else if (currentPage + 4 >= totalPages) 
          startPage = totalPages - 9;
          endPage = totalPages;
         else 
          startPage = currentPage - 5;
          endPage = currentPage + 4;
        
      

      // calculate start and end item indexes
      var startIndex = (currentPage - 1) * pageSize;
      var endIndex = Math.min(startIndex + pageSize - 1, totalItems - 1);

      // create an array of pages to ng-repeat in the pager control
      var pages = _.range(startPage, endPage + 1);

      // return object with all pager properties required by the view
      return 
        totalItems: totalItems,
        currentPage: currentPage,
        pageSize: pageSize,
        totalPages: totalPages,
        startPage: startPage,
        endPage: endPage,
        startIndex: startIndex,
        endIndex: endIndex,
        pages: pages
      ;
    
  
)();

HTML

<html ng-app="testApp">

<head>
  <meta charset="utf-8" />
  <title></title>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>

<body>
  <div class="contentWrapper">
    <div data-ng-controller="searchBtnCtrl as vm">
      <h3>Search:</h3>
      <input id="searchQuery" type="text" placeholder="enter your search query here" data-ng-model="searchInput" />

      <button id="searchBtn" data-ng-click="performSearch()">SEARCH</button>

      <div id="searchResults">
        <!-- items being paged --> 
        <div ng-repeat="post in vm.posts"> 
          <span class="post"><a href='post.title' alt='post.title'>post.title</a><br />post.body</span></div>

        <!-- pager -->
        <ul ng-if="vm.pager.pages.length" class="pagination">
          <li ng-class="disabled:vm.pager.currentPage === 1">
            <a ng-click="vm.setPage(1)">First</a>
          </li>
          <li ng-class="disabled:vm.pager.currentPage === 1">
            <a ng-click="vm.setPage(vm.pager.currentPage - 1)">Previous</a>
          </li>
          <li ng-repeat="page in vm.pager.pages" ng-class="active:vm.pager.currentPage === page">
            <a ng-click="vm.setPage(page)">page</a>
          </li>
          <li ng-class="disabled:vm.pager.currentPage === vm.pager.totalPages">
            <a ng-click="vm.setPage(vm.pager.currentPage + 1)">Next</a>
          </li>
          <li ng-class="disabled:vm.pager.currentPage === vm.pager.totalPages">
            <a ng-click="vm.setPage(vm.pager.totalPages)">Last</a>
          </li>
        </ul>
      </div>
    </div>
  </div>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
</body>

</html>

【讨论】:

哇,我做错了一些愚蠢的事情,但是感谢 Swain 和 lilo,它现在可以正常工作了。非常感激! :)

以上是关于AngularJS 1.6 分页不显示的主要内容,如果未能解决你的问题,请参考以下文章

XCode - UIScrollView 分页不显示子视图(自动布局?)

ng+ant分页不显示问题

gridview分页不显示数据

laypage不足一页不显示分页怎么办

当侧边栏在 single.php 中时,侧边栏分页不显示

thinkPHP5开发智慧软文遇到的分页第二页不显示数据的问题