You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular5:路由切换后ngOnInit仅触发一次致数据丢失问题求解

Ah, I've run into this exact issue with Angular routing before! The problem here is that Angular reuses component instances by default when navigating between routes. That means your ngOnInit hook only fires once when the component is first created, and doesn't trigger again when you navigate back to the Teams page later. Hence, your data doesn't reload, leaving you with an empty list until you refresh.

Here are a few solid solutions to fix this:

Solution 1: Force Component Reinitialization on Navigation

You can tell Angular to always recreate the Teams component whenever the route is visited by setting runGuardsAndResolvers: 'always' in your route configuration. This ensures ngOnInit runs every time you navigate to the page, reloading your data.

Update your routing module (e.g., app-routing.module.ts):

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { TeamsComponent } from './components/teams/teams.component';

const routes: Routes = [
  {
    path: 'teams',
    component: TeamsComponent,
    // Ensures the component is reinitialized on every navigation
    runGuardsAndResolvers: 'always'
  },
  // Add other routes here...
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Solution 2: Listen to Route Events to Reload Data Manually

If you prefer to reuse the component instance, you can subscribe to router navigation events and trigger a data reload whenever you return to the Teams page. This avoids recreating the component but still ensures fresh data.

Modify your TeamsComponent code:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { TeamsService } from '../../services/teams.service';
import { Team } from '../../models/team';
import { Observable, Subscription } from 'rxjs';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';

@Component({
  selector: "app-teams",
  templateUrl: "./teams.component.html",
  styleUrls: ["./teams.component.css"]
})
export class TeamsComponent implements OnInit, OnDestroy {
  public teams: Team[];
  editState: boolean = false;
  teamToEdit: Team;
  showAdd: boolean = false;
  showSelect: boolean = false;
  selectedTeam: Observable<Team>;
  private routerSubscription: Subscription;

  constructor(public teamsService: TeamsService, private router: Router) { }

  ngOnInit() {
    // Load data on initial component load
    this.loadTeams();

    // Listen for navigation end events to detect when we're back on the Teams page
    this.routerSubscription = this.router.events.pipe(
      filter(event => event instanceof NavigationEnd)
    ).subscribe((event: NavigationEnd) => {
      if (event.url.includes('/teams')) {
        this.loadTeams();
      }
    });
  }

  // Encapsulate data loading logic for reusability
  private loadTeams() {
    this.teamsService.getTeams().subscribe(teams => {
      this.teams = teams;
      console.log('Teams data reloaded');
    });
  }

  // Clean up subscription to prevent memory leaks
  ngOnDestroy() {
    if (this.routerSubscription) {
      this.routerSubscription.unsubscribe();
    }
  }

  // Keep your existing methods: deleteTeam, editTeam, updateTeam, etc.
}

The most elegant approach is to maintain your data state in the service using a BehaviorSubject. This way, the service holds the single source of truth for your teams data, and any component can subscribe to it to get the latest data—even when navigating back and forth.

First, update your TeamsService:

import { Injectable } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { Team } from '../models/team';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class TeamsService {
  // BehaviorSubject holds the current state of teams, with an empty array default
  private teamsSubject = new BehaviorSubject<Team[]>([]);
  // Expose an observable so components can subscribe without modifying the source
  public teams$: Observable<Team[]> = this.teamsSubject.asObservable();

  constructor(private afs: AngularFirestore) {
    // Listen to Firestore changes and update the subject automatically
    this.afs.collection<Team>('teams').valueChanges().subscribe(teams => {
      this.teamsSubject.next(teams);
    });
  }

  getTeamById(id: string): Observable<Team> {
    return this.afs.doc<Team>(`teams/${id}`).valueChanges();
  }

  deleteTeam(team: Team) {
    return this.afs.doc(`teams/${team.id}`).delete();
  }

  updateTeam(team: Team) {
    return this.afs.doc(`teams/${team.id}`).update(team);
  }

  // Add this if you need to create teams
  addTeam(team: Team) {
    return this.afs.collection('teams').add(team);
  }
}

Then modify your TeamsComponent to subscribe to the service's observable:

import { Component, OnInit } from '@angular/core';
import { TeamsService } from '../../services/teams.service';
import { Team } from '../../models/team';
import { Observable } from 'rxjs';

@Component({
  selector: "app-teams",
  templateUrl: "./teams.component.html",
  styleUrls: ["./teams.component.css"]
})
export class TeamsComponent implements OnInit {
  public teams: Team[];
  editState: boolean = false;
  teamToEdit: Team;
  showAdd: boolean = false;
  showSelect: boolean = false;
  selectedTeam: Observable<Team>;

  constructor(public teamsService: TeamsService) { }

  ngOnInit() {
    // Subscribe to the service's data stream to get real-time updates
    this.teamsService.teams$.subscribe(teams => {
      this.teams = teams;
      console.log('Received latest teams data');
    });
  }

  // Keep your existing methods unchanged
}

This method has several benefits:

  • It avoids redundant Firestore requests by keeping a cached copy of the data
  • All components using the service will get consistent, up-to-date data
  • You don't have to worry about route navigation affecting data availability

内容的提问来源于stack exchange,提问作者WestMD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:34:01