Aplicación paginada de publicaciones de AngularJS -- javascript campo con performance campo con angular.js campo con ajax campo con pagination camp codereview Relacionados El problema

Paginated AngularJS posts application


2
vote

problema

Español

He hecho una pequeña aplicación que muestra un Publicaciones JSON en forma de tarjetas, con la ayuda de Angularjs y Twitter Bootstrap 4.

La aplicación tiene una interfaz para Paginación y hay aproximadamente 100 puestos que se muestran en cada página.

  var root = 'https://jsonplaceholder.typicode.com';  // Create an Angular module named "postsApp" var app = angular.module("postsApp", []);  // Create controller for the "postsApp" module app.controller("postsCtrl", ["$scope", "$http", "$filter", function($scope, $http, $filter) {   var url = root + "/posts";   $scope.postList = [];   $scope.search = "";   $scope.filterList = function() {     var oldList = $scope.postList || [];     $scope.postList = $filter('filter')($scope.posts, $scope.search);     if (oldList.length != $scope.postList.length) {       $scope.pageNum = 1;       $scope.startAt = 0;     };     $scope.itemsCount = $scope.postList.length;     $scope.pageMax = Math.ceil($scope.itemsCount / $scope.perPage);   };   $http.get(url)     .then(function(data) {       // posts arary       $scope.posts = data.data;       $scope.filterList();        // Paginate       $scope.pageNum = 1;       $scope.perPage = 24;       $scope.startAt = 0;       $scope.filterList();        $scope.currentPage = function(index) {         $scope.pageNum = index + 1;         $scope.startAt = index * $scope.perPage;       };        $scope.prevPage = function() {         if ($scope.pageNum > 1) {           $scope.pageNum = $scope.pageNum - 1;           $scope.startAt = ($scope.pageNum - 1) * $scope.perPage;         }       };        $scope.nextPage = function() {         if ($scope.pageNum < $scope.pageMax) {           $scope.pageNum = $scope.pageNum + 1;           $scope.startAt = ($scope.pageNum - 1) * $scope.perPage;         }       };     }); }]);  
  .posts-grid {   margin-top: 25px;   display: flex;   flex-wrap: wrap; }  .posts-grid>[class*='col-'] {   display: flex;   flex-direction: column;   margin-bottom: 25px; }  .posts-grid .post {   background: #fff;   border-top: 1px solid #d5d5d5;   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.11); }  .posts-grid .text {   padding: 8px; }  .posts-grid .card-title {   font-size: 1.25rem;   margin-bottom: 8px;   text-transform: capitalize; }  .posts-grid .read-more {   padding: 0 8px 8px 8px; }  .posts-grid .text-muted {   margin-bottom: 8px; }  .posts-grid .thumbnail img {   display: block;   width: 100%;   height: auto; }  .posts-grid p {   text-align: justify; }  .posts-grid .post {   flex-grow: 1;   display: flex;   flex-direction: column; }  .posts-grid .read-more {   margin-top: auto; }  .pagination>li>a, .pagination>li>a:hover, .pagination>li>span {   color: #585858;   line-height: 1;   padding: 6px 12px;   text-decoration: none; }  .pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus {   background-color: #007bff;   border-color: #2b7c2b;   color: #fff; }  @media (max-width: 767px) {   .container {     max-width: 100%;   } }  @media (max-width: 575px) {   .container {     max-width: 100%;     padding-left: 0;     padding-right: 0;   }   .posts-grid>[class*='col-'] {     padding-left: 5px;     padding-right: 5px;   } }1  
  <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>  <nav class="navbar navbar-expand-md bg-dark navbar-dark sticky-top">   <!-- Brand -->   <a class="navbar-brand" href="#">My Blog</a>   <!-- Toggler/collapsibe Button -->   <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">    <span class="navbar-toggler-icon"></span>   </button>    <!-- Navbar links -->   <div class="collapse navbar-collapse" id="collapsibleNavbar">     <ul class="navbar-nav ml-auto">       <li class="nav-item">         <a class="nav-link active" href="#">Contacts</a>       </li>       <li class="nav-item">         <a class="nav-link" href="#">About us</a>       </li>       <li class="nav-item">         <a class="nav-link btn btn-outline-primary" href="#">Login</a>       </li>     </ul>   </div> </nav>  <div data-ng-app="postsApp">   <div class="container" data-ng-controller="postsCtrl">     <div class="row">       <div class="col-sm-9 mx-auto">         <div class="form-group search-box mt-3 px-3">           <input type="text" class="form-control" id="search" placeholder="Search post" data-ng-model="search" ng-change="filterList()">         </div>       </div>     </div>     <div class="posts-grid" ng-if="postList.length > 0">       <div class="col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-ng-repeat="post in postList | limitTo : perPage : startAt">         <div class="post">           <div class="thumbnail">             <img src="//lorempixel.com/450/300" />           </div>           <div class="text">             <h3 class="card-title">{{post.title}}</h3>             <p class="text-muted">{{post.body}}</p>           </div>           <div class="read-more">             <a class="btn btn-block btn-sm btn-primary" href="#">Read more</a>           </div>         </div>       </div>     </div>     <p ng-if="postList.length <= 0" class="text-center">There are no posts</p>     <div ng-if="pageMax > 1">       <ul class="pagination pagination-sm justify-content-center">         <li class="page-item"><a href="#" ng-click="prevPage()"><i class="fa fa-chevron-left"></i></a></li>         <li ng-repeat="n in [].constructor(pageMax) track by $index" ng-class="{true: 'active'}[$index == pageNum - 1]">           <a href="#" ng-click="currentPage($index)">{{$index+1}}</a>         </li>         <li><a href="#" ng-click="nextPage()"><i class="fa fa-chevron-right"></i></a></li>       </ul>     </div>   </div> </div>  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> <script>   $(document).ready(function($) {     $('.pagination > li > a').click(function() {       $("html, body").animate({         scrollTop: 0       }, 500);       return false;     });   }); </script>  

Algunas preguntas que nacen en mi mente recientemente y no encontré la respuesta, de ahí mi tema aquí:

  1. ¿Qué sucede si hay 10 o 100 veces más puestos, la aplicación tendría un problema de rendimiento (por ejemplo, la carga de la página)?
  2. existe una mejor manera de paginar la aplicación; uno que cargaría tantos artículos de posts.json como se muestra en una página (24 artículos), en lugar de todo el archivo JSON?
  3. ¿Cómo sería optimizar esta aplicación, en la parte delantera?
Original en ingles

I have made a small application that displays a posts JSON in the form of cards, with the help of AngularJS and Twitter Bootstrap 4.

The application has an interface for pagination and there are about 100 posts displayed on each page.

var root = 'https://jsonplaceholder.typicode.com';  // Create an Angular module named "postsApp" var app = angular.module("postsApp", []);  // Create controller for the "postsApp" module app.controller("postsCtrl", ["$scope", "$http", "$filter", function($scope, $http, $filter) {   var url = root + "/posts";   $scope.postList = [];   $scope.search = "";   $scope.filterList = function() {     var oldList = $scope.postList || [];     $scope.postList = $filter('filter')($scope.posts, $scope.search);     if (oldList.length != $scope.postList.length) {       $scope.pageNum = 1;       $scope.startAt = 0;     };     $scope.itemsCount = $scope.postList.length;     $scope.pageMax = Math.ceil($scope.itemsCount / $scope.perPage);   };   $http.get(url)     .then(function(data) {       // posts arary       $scope.posts = data.data;       $scope.filterList();        // Paginate       $scope.pageNum = 1;       $scope.perPage = 24;       $scope.startAt = 0;       $scope.filterList();        $scope.currentPage = function(index) {         $scope.pageNum = index + 1;         $scope.startAt = index * $scope.perPage;       };        $scope.prevPage = function() {         if ($scope.pageNum > 1) {           $scope.pageNum = $scope.pageNum - 1;           $scope.startAt = ($scope.pageNum - 1) * $scope.perPage;         }       };        $scope.nextPage = function() {         if ($scope.pageNum < $scope.pageMax) {           $scope.pageNum = $scope.pageNum + 1;           $scope.startAt = ($scope.pageNum - 1) * $scope.perPage;         }       };     }); }]);
.posts-grid {   margin-top: 25px;   display: flex;   flex-wrap: wrap; }  .posts-grid>[class*='col-'] {   display: flex;   flex-direction: column;   margin-bottom: 25px; }  .posts-grid .post {   background: #fff;   border-top: 1px solid #d5d5d5;   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.11); }  .posts-grid .text {   padding: 8px; }  .posts-grid .card-title {   font-size: 1.25rem;   margin-bottom: 8px;   text-transform: capitalize; }  .posts-grid .read-more {   padding: 0 8px 8px 8px; }  .posts-grid .text-muted {   margin-bottom: 8px; }  .posts-grid .thumbnail img {   display: block;   width: 100%;   height: auto; }  .posts-grid p {   text-align: justify; }  .posts-grid .post {   flex-grow: 1;   display: flex;   flex-direction: column; }  .posts-grid .read-more {   margin-top: auto; }  .pagination>li>a, .pagination>li>a:hover, .pagination>li>span {   color: #585858;   line-height: 1;   padding: 6px 12px;   text-decoration: none; }  .pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus {   background-color: #007bff;   border-color: #2b7c2b;   color: #fff; }  @media (max-width: 767px) {   .container {     max-width: 100%;   } }  @media (max-width: 575px) {   .container {     max-width: 100%;     padding-left: 0;     padding-right: 0;   }   .posts-grid>[class*='col-'] {     padding-left: 5px;     padding-right: 5px;   } }
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script>  <nav class="navbar navbar-expand-md bg-dark navbar-dark sticky-top">   <!-- Brand -->   <a class="navbar-brand" href="#">My Blog</a>   <!-- Toggler/collapsibe Button -->   <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">    <span class="navbar-toggler-icon"></span>   </button>    <!-- Navbar links -->   <div class="collapse navbar-collapse" id="collapsibleNavbar">     <ul class="navbar-nav ml-auto">       <li class="nav-item">         <a class="nav-link active" href="#">Contacts</a>       </li>       <li class="nav-item">         <a class="nav-link" href="#">About us</a>       </li>       <li class="nav-item">         <a class="nav-link btn btn-outline-primary" href="#">Login</a>       </li>     </ul>   </div> </nav>  <div data-ng-app="postsApp">   <div class="container" data-ng-controller="postsCtrl">     <div class="row">       <div class="col-sm-9 mx-auto">         <div class="form-group search-box mt-3 px-3">           <input type="text" class="form-control" id="search" placeholder="Search post" data-ng-model="search" ng-change="filterList()">         </div>       </div>     </div>     <div class="posts-grid" ng-if="postList.length > 0">       <div class="col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-ng-repeat="post in postList | limitTo : perPage : startAt">         <div class="post">           <div class="thumbnail">             <img src="//lorempixel.com/450/300" />           </div>           <div class="text">             <h3 class="card-title">{{post.title}}</h3>             <p class="text-muted">{{post.body}}</p>           </div>           <div class="read-more">             <a class="btn btn-block btn-sm btn-primary" href="#">Read more</a>           </div>         </div>       </div>     </div>     <p ng-if="postList.length <= 0" class="text-center">There are no posts</p>     <div ng-if="pageMax > 1">       <ul class="pagination pagination-sm justify-content-center">         <li class="page-item"><a href="#" ng-click="prevPage()"><i class="fa fa-chevron-left"></i></a></li>         <li ng-repeat="n in [].constructor(pageMax) track by $index" ng-class="{true: 'active'}[$index == pageNum - 1]">           <a href="#" ng-click="currentPage($index)">{{$index+1}}</a>         </li>         <li><a href="#" ng-click="nextPage()"><i class="fa fa-chevron-right"></i></a></li>       </ul>     </div>   </div> </div>  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script> <script>   $(document).ready(function($) {     $('.pagination > li > a').click(function() {       $("html, body").animate({         scrollTop: 0       }, 500);       return false;     });   }); </script>

A few questions ware born in my mind recently and I did not find the answer, hence my topic here:

  1. What if there ware 10 or 100 times as many posts, would the application have a performance problem (e.g. with page load)?
  2. Is there a better way to paginate the application; one that would load as many items from posts.json as there are displayed on one page (24 items), instead of the entire JSON file?
  3. How would you optimize this application, on the front end?
              
     
     

Lista de respuestas

1
 
vote
vote
La mejor respuesta
 
  1. ¿Qué sucede si hay 10 o 100 veces más puestos, ¿la aplicación tendría un problema de rendimiento (carga de página)?

Pruébelo con 10 veces más publicaciones . Sé que solo duplica cada publicación 10 veces sin modificar los valores únicos como id pero debe demostrar el rendimiento. Puedo ver los enlaces de páginas, pero a menos que haga la pantalla completa de la ventana y aleje (en mi monitor de 24 "), no puedo ver los enlaces de todas las páginas, por ejemplo, el enlace para la página 1 se corta, así como cualquier cosa más allá Página 42.

  1. existe una mejor manera de paginar la aplicación; uno que cargaría tantos elementos de Posts.json, ya que se muestran en una página (24 artículos), en lugar de todo el archivo JSON?

A menos que el punto final de la API acepte un parámetro para el tamaño de la página, es probable que deba utilizar un idioma de scripting de lado del servidor como Python, Ruby en rieles, PHP, C #, vb.net, asp, etc. que podría devolver el Pagesize especificada.

  1. ¿Cómo optimizarías esta aplicación, en la parte delantera?

No veo mucho que se destaca como un lugar obvio para optimizar, aunque sí me doy cuenta de que la devolución de llamada de promesa a $http.get(url) tiene dos llamadas a fibb(4)0 separado por Tres líneas de asignación:

  fibb(4)1  

¿Hay alguna forma de reducir las dos llamadas a una sola llamada allí? Tal vez la primera llamada no es necesaria?

Luego, mirando esa promesa de devolución de llamada, veo los tres métodos establecidos en fibb(4)2 allí: 99887776655443313 , fibb(4)4 y fibb(4)5 < / Código>. Recomendaría mover esos métodos fuera del manejador de devoluciones de llamada, de modo que todo lo que hace se configura los datos posteriores en fibb(4)6 y las variables de paginación relacionadas.

También veo un defecto con el código jQuery utilizado para desplazarse a la parte superior ( que no parece estar funcionando porque no hay elementos que coincidan con el selector fibb(4)7 Cuando se carga el DOM). Intenté encontrar un equivalente en Angularjs, pero encontré poco ... hay una solución que encontré desde esta publicación que usa aanillajs. Tuve que alterar los atributos fibb(4)8 en los anclajes para usarlo.

  fibb(4)9  

Luego, que se puede utilizar en los métodos de accionamiento de clics:

  $limit0  

Aunque para detener la navegación de anclaje, será necesario prevenir el manejo de eventos predeterminado:

  $limit1  

Código actualizado

Consulte el código modificado a continuación.

  $limit2  
  $limit3  
  $limit4  
 
  1. What if there ware 10 or 100 times as many posts, would the application have a performance (page load) problem?

Try it with 10 times as many posts. I know that just duplicates each post 10 times without modifying the unique values like id but it should demonstrate the performance. I can see the page links but unless I make the window full screen and zoom out (on my 24" monitor) I can't see the all the page links - e.g. the link for Page 1 is cut off, as well as anything beyond page 42.

  1. Is there a better way to paginate the application; one that would load as many items from posts.json as there are displayed on one page (24 items), instead of the entire JSON file?

Unless the API endpoint accepts a parameter for the page size, you would likely need to utilize a server-side scripting language like Python, Ruby on Rails, PHP, C#, VB.NET, ASP, etc. which could return the specified pagesize.

  1. How would you optimize this application, on the front end?

I don't see much that stands out as an obvious place to optimize, though I do notice that the promise callback to $http.get(url) has two calls to filterList() separated by three assignment lines:

$http.get(url)     .then(function(data) {       // posts arary       $scope.posts = data.data;       $scope.filterList();        // Paginate       $scope.pageNum = 1;       $scope.perPage = 24;       $scope.startAt = 0;       $scope.filterList(); 

Is there any way to reduce the two calls to a single call there? Perhaps the first call is not needed?

Then looking at that promise callback, I see the three methods set on $scope there: currentPage, prevPage and nextPage. I would recommend moving those methods out of the callback handler, so that all it does is set the post data on $scope and related paging variables.

Also, I see a flaw with the jQuery code used for scrolling to the top (which doesn't appear to be working because there are no elements matching the selector .pagination > li > a when the DOM is loaded). I tried finding an equivalent in AngularJS but found little... There is a solution I found from this post that uses vanillaJS. I had to alter the href attributes on the anchors to use it.

$scope.scrollToTop = function() {     var scrollDuration = 500;     var scrollStep = -window.scrollY / (scrollDuration / 10);      var scrollInterval = setInterval(function() {       if (window.scrollY != 0) {         window.scrollBy(0, scrollStep);       } else {         clearInterval(scrollInterval);       }     }, 15);   }; 

Then that can be used in the click handler methods:

  $scope.currentPage = function(index) {     $scope.pageNum = index + 1;     $scope.startAt = index * $scope.perPage;     $scope.scrollToTop();   }; 

Though in order to stop the anchor navigation, the default event handling will need to be prevented:

<a href="#" ng-click="currentPage($index); $event.preventDefault();">{{$index+1}}</a> 

Updated code

See modified code below.

var root = 'https://jsonplaceholder.typicode.com';  // Create an Angular module named "postsApp" var app = angular.module("postsApp", []);  // Create controller for the "postsApp" module app.controller("postsCtrl", ["$scope", "$http", "$filter", function($scope, $http, $filter) {   var url = root + "/posts";   $scope.postList = [];   $scope.search = "";   $scope.filterList = function() {     var oldList = $scope.postList || [];     $scope.postList = $filter('filter')($scope.posts, $scope.search);     if (oldList.length != $scope.postList.length) {       $scope.pageNum = 1;       $scope.startAt = 0;     };     $scope.itemsCount = $scope.postList.length;     $scope.pageMax = Math.ceil($scope.itemsCount / $scope.perPage);   };     $scope.currentPage = function(index) {     $scope.pageNum = index + 1;     $scope.startAt = index * $scope.perPage;     $scope.scrollToTop();   };    $scope.prevPage = function() {     if ($scope.pageNum > 1) {       $scope.pageNum = $scope.pageNum - 1;       $scope.startAt = ($scope.pageNum - 1) * $scope.perPage;       $scope.scrollToTop();     }   };    $scope.nextPage = function() {     if ($scope.pageNum < $scope.pageMax) {       $scope.pageNum = $scope.pageNum + 1;       $scope.startAt = ($scope.pageNum - 1) * $scope.perPage;       $scope.scrollToTop();     }   };   $scope.scrollToTop = function() {     var scrollDuration = 500;     var scrollStep = -window.scrollY / (scrollDuration / 10);      var scrollInterval = setInterval(function() {       if (window.scrollY != 0) {         window.scrollBy(0, scrollStep);       } else {         clearInterval(scrollInterval);       }     }, 15);   };   $http.get(url)     .then(function(data) {       // posts arary       $scope.posts = data.data;       $scope.filterList();        // Paginate       $scope.pageNum = 1;       $scope.perPage = 24;       $scope.startAt = 0;       $scope.filterList();     }); }]);
.posts-grid {   margin-top: 25px;   display: flex;   flex-wrap: wrap; }  .posts-grid>[class*='col-'] {   display: flex;   flex-direction: column;   margin-bottom: 25px; }  .posts-grid .post {   background: #fff;   border-top: 1px solid #d5d5d5;   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.11); }  .posts-grid .text {   padding: 8px; }  .posts-grid .card-title {   font-size: 1.25rem;   margin-bottom: 8px;   text-transform: capitalize; }  .posts-grid .read-more {   padding: 0 8px 8px 8px; }  .posts-grid .text-muted {   margin-bottom: 8px; }  .posts-grid .thumbnail img {   display: block;   width: 100%;   height: auto; }  .posts-grid p {   text-align: justify; }  .posts-grid .post {   flex-grow: 1;   display: flex;   flex-direction: column; }  .posts-grid .read-more {   margin-top: auto; }  .pagination>li>a, .pagination>li>a:hover, .pagination>li>span {   color: #585858;   line-height: 1;   padding: 6px 12px;   text-decoration: none; }  .pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus {   background-color: #007bff;   border-color: #2b7c2b;   color: #fff; }  @media (max-width: 767px) {   .container {     max-width: 100%;   } }  @media (max-width: 575px) {   .container {     max-width: 100%;     padding-left: 0;     padding-right: 0;   }   .posts-grid>[class*='col-'] {     padding-left: 5px;     padding-right: 5px;   } }
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" /> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>   <nav class="navbar navbar-expand-md bg-dark navbar-dark sticky-top">   <!-- Brand -->   <a class="navbar-brand" href="#">My Blog</a>   <!-- Toggler/collapsibe Button -->   <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">    <span class="navbar-toggler-icon"></span>   </button>    <!-- Navbar links -->   <div class="collapse navbar-collapse" id="collapsibleNavbar">     <ul class="navbar-nav ml-auto">       <li class="nav-item">         <a class="nav-link active" href="#">Contacts</a>       </li>       <li class="nav-item">         <a class="nav-link" href="#">About us</a>       </li>       <li class="nav-item">         <a class="nav-link btn btn-outline-primary" href="#">Login</a>       </li>     </ul>   </div> </nav>  <div data-ng-app="postsApp">   <div class="container" data-ng-controller="postsCtrl">     <div class="row">       <div class="col-sm-9 mx-auto">         <div class="form-group search-box mt-3 px-3">           <input type="text" class="form-control" id="search" placeholder="Search post" data-ng-model="search" ng-change="filterList()">         </div>       </div>     </div>     <div class="posts-grid" ng-if="postList.length > 0">       <div class="col-xs-12 col-sm-6 col-lg-4 col-xl-3" data-ng-repeat="post in postList | limitTo : perPage : startAt">         <div class="post">           <div class="thumbnail">             <img src="//lorempixel.com/450/300" />           </div>           <div class="text">             <h3 class="card-title">{{post.title}}</h3>             <p class="text-muted">{{post.body}}</p>           </div>           <div class="read-more">             <a class="btn btn-block btn-sm btn-primary" href="#">Read more</a>           </div>         </div>       </div>     </div>     <p ng-if="postList.length <= 0" class="text-center">There are no posts</p>     <div ng-if="pageMax > 1">       <ul class="pagination pagination-sm justify-content-center">         <li class="page-item"><a href="#" ng-click="prevPage(); $event.preventDefault();"><i class="fa fa-chevron-left"></i></a></li>         <li ng-repeat="n in [].constructor(pageMax) track by $index" ng-class="{true: 'active'}[$index == pageNum - 1]">           <a href="#" ng-click="currentPage($index); $event.preventDefault();">{{$index+1}}</a>         </li>         <li><a href="#" ng-click="nextPage(); $event.preventDefault();"><i class="fa fa-chevron-right"></i></a></li>       </ul>     </div>   </div> </div>
 
 
     
     

Relacionados problema

3  Filtrado de paginación  ( Pagination filtering ) 
Quiero verificar si hay variable de página (en URL) y, si es, si es correcto, no puede ser el número 1 porque esta es una página predeterminada y debe ser v...

5  Paginación de Laravel con fórmula haversina en ella  ( Laravel pagination with haversine formula in it ) 
Estoy usando la fórmula de Haversine para contar la distancia del código postal seleccionado al destino deseado. Tengo el siguiente scope en AppModelsBus...

8  Paginando grandes resultados de SQL  ( Paginating large sql results ) 
Se siente como la paginación es una de las preguntas más discutidas en la web, que siempre termina con algunos hacks rápidos y sucios sobre cómo pagarse. Quie...

2  Función para filtrar comentarios y calificaciones, con soporte de paginación  ( Function to filter comments and ratings with pagination support ) 
Tengo un componente web que está haciendo una lista de elementos y tengo este método para filtrar estos elementos basados ​​en un objeto 998877666554433320 ...

1  Paginación con datos estáticos  ( Pagination with static data ) 
Estoy usando el siguiente código para implementar la funcionalidad de paginación. Todos los artículos están procesados ​​en la carga de la página y seconds::...

8  Transmisión de páginas de un tamaño diferente a las páginas de un caché  ( Streaming pages of a different size than a caches pages ) 
Necesito escribir un servicio para devolver objetos en las páginas del tamaño 20. El almacenamiento en caché de estos objetos se realiza en páginas de tamaño ...

7  Versión de C # StringBuilder para permitir cadenas mayores de 2 mil millones de caracteres  ( Version of c stringbuilder to allow for strings larger than 2 billion character ) 
En las ventanas C #, 64bit, .NET 4.5 (o posterior) y habilitando gcAllowVeryLargeObjects en el archivo App.config permite objetos mayores de dos gigabytes. ...

8  Paginación infinita de desplazamiento con un diseño de Wookmark  ( Infinite scroll pagination with a wookmark layout ) 
class ProgramssController < ApplicationController def index @programs = Program.paginate :page => params[:page], :per_page => params[:per_page] || 30 ...

5  Función PHP de la paginación: ¿puede este código ser hecho más eficiente?  ( Pagination php function can this code be made more efficient ) 
En primer lugar, no escribí este código desde cero, estoy bastante seguro de que lo tomé de un tutorial en línea y lo modificé ligeramente para satisfacer mis...

7  Plugin de paginación  ( Pagination plugin ) 
Este complemento está escrito en jQuery y se hace para admitir el marco de CodeIgniter . Es un complemento de paginación de tabla de AJAX diseñada para propo...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos