• Skip to main content
  • Skip to primary sidebar

Web Development Archive

  • Archive
You are here: Home / Other / Pagination

Pagination

Component

import { Component, OnInit } from '@angular/core';
import { MovieService } from '../movies.service';
import { BehaviorSubject, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { CommonModule } from '@angular/common';

@Component({
  selector: 'app-pagination',
  templateUrl: './pagination.component.html',
  styleUrls: ['./pagination.component.scss'],
  standalone: true,
  imports: [CommonModule],
})
export class PaginationComponent implements OnInit {
  constructor(private readonly movieService: MovieService) {}
  items$ = this.movieService.getAllMovies$();

  currentPage$ = new BehaviorSubject<number>(1);
  itemsPerPage = 4;

  displayedItems$ = combineLatest([this.items$, this.currentPage$]).pipe(
    map(([items, currentPage]) => items.slice((currentPage - 1) * this.itemsPerPage, currentPage * this.itemsPerPage))
  );

  totalItems: number;

  get totalPages(): number {
    return Math.ceil(this.totalItems / this.itemsPerPage);
  }

  previousPage(): void {
    this.currentPage$.next(this.currentPage$.value - 1);
  }

  nextPage(): void {
    this.currentPage$.next(this.currentPage$.value + 1);
  }

  ngOnInit(): void {
    this.items$.subscribe((items) => {
      this.totalItems = items.length;
    });
  }
}

Template

<h2>Movies</h2>
<div class="movies grid-4">
  <div class="card" *ngFor="let item of displayedItems$ | async">
    <img class="card-img-top" [src]="item.image" [alt]="item.title" />
    <h4 class="card-header">{{ item.title }}</h4>
    <ul class="list-group list-group-flush">
      <li class="list-group-item">Year: {{ item.year }}</li>
      <li class="list-group-item">Genre: {{ item.genre }}</li>
      <li class="list-group-item">IMDb Rating: {{ item.imdb }}</li>
    </ul>
    <div class="card-footer"></div>
  </div>
</div>

<div *ngIf="totalItems > itemsPerPage" class="pagination">
  <button [disabled]="currentPage$.value === 1" (click)="previousPage()">Previous</button>
  <button [disabled]="currentPage$.value === totalPages" (click)="nextPage()">Next</button>
</div>

A pagináció hozzáadásához szükség lesz néhány módosításra az alkalmazásban. Az alábbiakban felsorolom a lépéseket, amiket meg kell tenni:

  1. Változók hozzáadása a MoviesComponent-hez:
  • currentPage: az aktuális oldal száma
  • itemsPerPage: hány elem jelenjen meg egy oldalon
  • totalItems: a teljes filmek száma (opcionális, de hasznos a navigációhoz)
  1. Szűrő funkció az items$ streamhez, hogy csak a kiválasztott oldal elemeit mutassa.
  2. Navigációs gombok hozzáadása az oldal aljára/elére, hogy a felhasználók lapozhassanak.

Lássuk, hogyan nézhet ki ez:

1. Változók hozzáadása:

currentPage = 1;
itemsPerPage = 4;
totalItems: number;

ngOnInit() {
  // Eltároljuk a teljes filmek számát
  this.items$.subscribe(items => {
    this.totalItems = items.length;
  });
}

2. Items$ szűrése:

Mielőtt az items$-t használnánk az Angular template-ben, szűrnünk kell rajta, hogy csak a megfelelő oldal filmjeit mutassa. A slice metódust használhatjuk erre:

displayedItems$ = this.items$.pipe(
  map(items => items.slice((this.currentPage - 1) * this.itemsPerPage, this.currentPage * this.itemsPerPage))
);

A template-ben pedig cseréljük le items$-t displayedItems$-re.

3. Navigációs gombok:

<div *ngIf="totalItems > itemsPerPage" class="pagination">
  <button [disabled]="currentPage === 1" (click)="previousPage()">Previous</button>
  <button [disabled]="currentPage === (totalItems / itemsPerPage)" (click)="nextPage()">Next</button>
</div>

A komponensben:

previousPage(): void {
  if (this.currentPage > 1) {
    this.currentPage--;
  }
}

nextPage(): void {
  if (this.currentPage < this.totalItems / this.itemsPerPage) {
    this.currentPage++;
  }
}

Filed Under: Other

About Gabor Flamich

I'm a web developer and designer based in Budapest, Hungary. In recent years, I've documented hundreds of solutions I came across during development. This site is an archive for useful code snippets on WordPress, Genesis Framework and WooCommerce. If You have any questions related to WordPress development, get in touch!

Primary Sidebar

  • angular.io
© 2026 WP Flames - All Right Reserved