为何刷新页面时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()完全不触发。
我通过两种方式验证了该现象:
- 控制台打印
console.log('ngOnInit triggered');日志; - 开发者工具的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
相关产品推荐
相关产品推荐

