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

为何刷新页面时dashboard组件ngOnInit触发而edit-profile组件不触发?

Angular组件刷新后ngOnInit触发异常问题

我正在使用PEAN栈(PostgreSQL - ExpressJS - Angular - NodeJS)开发一个认证应用,包含两个组件:dashboard.component.ts和edit-profile.component.ts,二者均在ngOnInit()中订阅getUser方法,核心代码如下:

ngOnInit(): void {
  console.log('ngOnInit triggered');
  this.authService.getUser().subscribe(this.getUserObserver);
}

问题现象

刷新页面(如按F5键)时:

  • dashboard.component.ts的ngOnInit()会正常触发;
  • edit-profile.component.ts的ngOnInit()完全不触发。

我通过两种方式验证了该现象:

  1. 控制台打印console.log('ngOnInit triggered');日志;
  2. 开发者工具的Network标签监控请求。

具体表现:

  • 刷新dashboard.component.ts页面:控制台显示对应日志,Network标签有get-user请求;
  • 刷新edit-profile.component.ts页面:控制台无日志输出,Network标签无get-user请求。

疑问

为何刷新dashboard.component.ts页面时ngOnInit()会触发,而刷新edit-profile.component.ts页面时却不触发?

注:两个组件代码存在差异,但我认为组件内部代码并非问题根源,最大区别在于路由配置。以下是app-routing.module.ts的相关代码:

const routes: Routes = [
  { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  { path: 'dashboard', component: DashboardComponent },
  { path: 'dashboard/:token', component: DashboardComponent, canActivate: [IfSignedIn] },
  {
    path: 'profile',
    component: MainProfileComponent,
    canActivate: [IfSignedIn],
    children: [
      { path: 'edit-profile', component: EditProfileComponent, canActivate: [IfSignedIn] },
    ],
  },
];

补充:组件完整代码

dashboard.component.ts

import { Component, OnInit } from '@angular/core';
import { AuthService } from 'src/app/services/auth/auth.service';
import { Router } from '@angular/router';
import { MatSnackBar } from '@angular/material/snack-bar';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss'],
})
export class DashboardComponent implements OnInit {
  showUserData: any = '';

  readonly getUserObserver = {
    next: (x: any) => {    
      this.showUserData = x;
    },

    error: (err: any) => {
      if (err.status == 401) {
        this.snackBar.open('Token invalid', 'Close', {
          duration: 5000,
          panelClass: ['red-snackbar'],
        });
      }

      if (err.status == 500) {
        this.snackBar.open('Internal server error', 'Close', {
          duration: 5000,
          panelClass: ['red-snackbar'],
        });
      }
    },
  };

  readonly editProfileConfirmationObserver = {
    next: (x: any) => {
      this.dashboardRouter.navigateByUrl('/refresh', { skipLocationChange: true }).then(() => {
        this.snackBar.open('Profile changes saved successfully', 'Close', {
          duration: 5000,
          panelClass: ['green-snackbar'],
        });
      });
    },

    error: (err: any) => {
      if (err.status == 401) {
        this.snackBar.open('Link invalid or expired, please edit your profile again', 'Close', {
          duration: 5000,
          panelClass: ['red-snackbar'],
        });
      }
    },
  };

  constructor(private authService: AuthService, private dashboardRouter: Router, private snackBar: MatSnackBar) {}

  ngOnInit(): void {
    console.log('ngOnInit triggered');
    this.authService.getUser().subscribe(this.getUserObserver);
    this.authService.editProfileConfirmationLink().subscribe(this.editProfileConfirmationObserver);
 }
}

edit-profile.component.ts

import { Component, OnInit } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { FormControl } from '@angular/forms';
import { Validators } from '@angular/forms';
import { AuthService } from 'src/app/services/auth/auth.service';
import { Router } from '@angular/router';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatDialog } from '@angular/material/dialog';
import { EditProfileDialogComponent } from './dialogs/edit-profile-dialog/edit-profile-dialog.component';

@Component({
  selector: 'app-edit-profile',
  templateUrl: './edit-profile.component.html',
  styleUrls: ['./edit-profile.component.scss'],
})
export class EditProfileComponent implements OnInit {
  oldEmail: string = 'Initial value';
  showUserData: any = '';

  formEditProfile = new FormGroup({
    editProfileEmail: new FormControl('', [
      Validators.required,
      Validators.pattern('^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$'),
    ]),
  });

  getErrorMessageEmail() {
    if (this.formEditProfile.controls['editProfileEmail'].hasError('required')) {
      return 'Email is required';
    }

    return this.formEditProfile.controls['editProfileEmail'].hasError('pattern') ? 'Not valid email' : '';
  }

  readonly getUserObserver = {
    next: (x: any) => {
      this.showUserData = x;

      this.oldEmail = x.email;
    },

    error: (err: any) => {
      this.snackBar.open('User data fetched unsuccessfully', 'Close', {
        duration: 5000,
        panelClass: ['red-snackbar'],
      });
    },
  };

  onSubmitEditProfile() {
    const editProfileObserver = {
      next: (x: any) => {
        this.editProfileDialog.open(EditProfileDialogComponent, {
          panelClass: 'custom-dialog-container',
          width: '550px',
        });
      },

      error: (err: any) => {
        if (err.status == 409) {
          this.snackBar.open(err.error.message, 'Close', {
            duration: 5000,
            panelClass: ['red-snackbar'],
          });
        }

        if (err.status == 401) {
          this.snackBar.open('Token invalid or expired, please try again', 'Close', {
            duration: 5000,
            panelClass: ['red-snackbar'],
          });
        }

        if (err.status == 400) {
          this.snackBar.open('Something went wrong', 'Close', {
            duration: 5000,
            panelClass: ['red-snackbar'],
          });
        }

        if (err.status == 500) {
          this.snackBar.open('Internal server error', 'Close', {
            duration: 5000,
            panelClass: ['red-snackbar'],
          });
        }
      },
    };
    this.authService.editProfileNewEmail(this.formEditProfile.value.editProfileEmail!).subscribe(editProfileObserver);
  }

  constructor(private authService: AuthService, private editProfileRouter: Router, private snackBar: MatSnackBar, private editProfileDialog: MatDialog) {}

  ngOnInit(): void {
    console.log('ngOnInit triggered');
    this.authService.getUser().subscribe(this.getUserObserver);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 20:35:08