Angular中Firestore分页实现及页面切换数据不更新问题求助
Hey there! Let's break down your two issues step by step—first the pagination with Firebase Firestore, then the data refresh problem when navigating back to the Home page.
1. 实现每页2条的分页功能
You're right to use Firestore's startAt/endAt methods for pagination. Here's how to integrate them into your existing code:
Step 1: Update the ItemService
We'll add pagination-specific methods to track the last loaded item and fetch pages incrementally:
import { Injectable } from '@angular/core'; import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore'; import { Observable } from 'rxjs/Observable'; import { Item } from '../models/item'; @Injectable() export class ItemService { private lastVisibleItem: Item | null = null; constructor(public afs: AngularFirestore) { } // Fetch paginated items (pass lastItem to get next page) getPaginatedItems(pageSize: number, lastItem?: Item): Observable<Item[]> { let query = this.afs.collection('items', ref => { let baseQuery = ref.orderBy('title', 'desc'); // Start from the last item of the previous page if it exists if (lastItem) { baseQuery = baseQuery.startAt(lastItem.title); } // Fetch one extra item to check if there's more data available return baseQuery.limit(pageSize + 1); }); return query.snapshotChanges().map(changes => { const items = changes.map(a => { const data = a.payload.doc.data() as Item; data.id = a.payload.doc.id; return data; }); // Update last visible item and trim extra item if needed if (items.length > pageSize) { this.lastVisibleItem = items.pop(); } else { this.lastVisibleItem = null; // No more pages left } return items; }); } // Check if there are more items to load hasMoreItems(): boolean { return !!this.lastVisibleItem; } }
Step 2: Update the ItemsComponent
Add logic to load the first page and handle "Next Page" clicks:
import { Component, OnInit } from '@angular/core'; import { ItemService } from '../../services/item.service'; import { Item } from '../../models/item'; @Component({ selector: 'app-items', templateUrl: './items.component.html', styleUrls: ['./items.component.css'] }) export class ItemsComponent implements OnInit { items: Item[] = []; editState: boolean = false; itemToEdit: Item; readonly pageSize = 2; isLoading = false; constructor(private itemService: ItemService) { } ngOnInit() { // Load first page on component initialization this.loadFirstPage(); } loadFirstPage() { this.isLoading = true; this.itemService.getPaginatedItems(this.pageSize).subscribe(items => { this.items = items; this.isLoading = false; }); } loadNextPage() { if (!this.itemService.hasMoreItems() || this.isLoading) return; this.isLoading = true; this.itemService.getPaginatedItems(this.pageSize, this.itemService['lastVisibleItem']).subscribe(newItems => { this.items = newItems; // Replace current items with next page this.isLoading = false; }); } }
Step 3: Add Pagination Button to Template
Add this to your items.component.html to let users trigger the next page:
<button (click)="loadNextPage()" [disabled]="!itemService.hasMoreItems() || isLoading" > {{ isLoading ? 'Loading...' : 'Next Page' }} </button>
2. 切换页面后回到Home数据不更新的原因及解决方法
This issue typically stems from one of two common causes:
Cause 1: Component Reuse by Angular Router
Angular reuses component instances when navigating between routes with no parameter changes, so ngOnInit doesn't re-run—and your data subscription doesn't refresh.
Fix: Disable component reuse for the Home route
Add runGuardsAndResolvers: 'always' to your Home route configuration:
const routes: Routes = [ { path: 'home', component: ItemsComponent, runGuardsAndResolvers: 'always' }, // Your other routes (mat, training) go here ];
Cause 2: Firestore Local Cache
Firestore caches data by default, so when you return to the Home page, it might load cached data instead of fetching the latest from the server.
Fix: Force server-side data fetch
Modify the collection query in ItemService to skip the cache:
let query = this.afs.collection('items', ref => { // Your existing query logic here }, { source: 'server' }); // Force fetch from server
Bonus Fix: Re-subscribe on Route Activation
If you want to keep component reuse but still refresh data, subscribe to route activation events:
import { ActivatedRoute } from '@angular/router'; // Add to component constructor constructor(private itemService: ItemService, private route: ActivatedRoute) { } ngOnInit() { // Refresh data every time the route is activated this.route.url.subscribe(() => { this.loadFirstPage(); }); }
内容的提问来源于stack exchange,提问作者pette_mm

