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:
- Változók hozzáadása a MoviesComponent-hez:
currentPage: az aktuális oldal számaitemsPerPage: hány elem jelenjen meg egy oldalontotalItems: a teljes filmek száma (opcionális, de hasznos a navigációhoz)
- Szűrő funkció az
items$streamhez, hogy csak a kiválasztott oldal elemeit mutassa. - 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++;
}
}