Angular 10 页面刷新时如何等待用户信息API加载完成再访问数据
Angular异步用户数据加载等待方案
下面是3种可直接落地的实现方式,可根据你的业务场景选择:
方案1:路由Resolve守卫预加载(优先推荐)
通过Angular自带的Resolve守卫,在仪表盘路由激活前先完成用户数据加载,组件初始化时可直接拿到完整数据,不会出现null问题。
- 第一步:创建用户数据预加载守卫
// user.resolve.ts import { Injectable } from '@angular/core'; import { Resolve, Router } from '@angular/router'; import { UserService } from './user.service'; import { catchError, of } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class UserResolve implements Resolve<any> { constructor(private userService: UserService, private router: Router) {} resolve() { return this.userService.loadUserInfo().pipe( catchError(() => { // 数据加载失败时跳转到登录页 this.router.navigate(['/login']); return of(null); }) ); } }
- 第二步:修改路由配置,给仪表盘路由绑定Resolve守卫
// app-routing.module.ts const routes: Routes = [ { path: 'dashboard', component: DashboardComponent, resolve: { userInfo: UserResolve } }, // 其他路由配置保持不变 ];
- 第三步:仪表盘组件直接取预加载完成的数据
// dashboard.component.ts import { ActivatedRoute } from '@angular/router'; constructor(private route: ActivatedRoute) {} ngOnInit() { const userInfo = this.route.snapshot.data['userInfo']; // 直接执行业务逻辑即可,userInfo已经加载完成 }
方案2:全局服务+BehaviorSubject做响应式状态管理
如果需要多组件共享用户数据,可以用服务托管用户状态,组件订阅数据变化触发业务逻辑。
- 第一步:创建带状态管理的用户服务
// user.service.ts import { Injectable } from '@angular/core'; import { BehaviorSubject, tap } from 'rxjs'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class UserService { // 用BehaviorSubject存储用户状态,初始值为null private userInfoSub = new BehaviorSubject<any>(null); public userInfo$ = this.userInfoSub.asObservable(); constructor(private http: HttpClient) {} loadUserInfo() { return this.http.get('/api/user/info').pipe( tap(userInfo => this.userInfoSub.next(userInfo)) ); } }
- 第二步:保持在App组件的ngOnInit中调用
this.userService.loadUserInfo()触发数据加载 - 第三步:仪表盘组件订阅用户数据,过滤空值后执行业务逻辑
// dashboard.component.ts import { UserService } from './user.service'; import { filter } from 'rxjs'; constructor(private userService: UserService) {} ngOnInit() { this.userService.userInfo$.pipe( // 过滤掉初始null值,只有数据加载完成后才会触发后续逻辑 filter(userInfo => !!userInfo) ).subscribe(userInfo => { // 在此处执行依赖用户数据的业务逻辑 }); }
方案3:模板层加判断延迟渲染
如果UI完全依赖用户数据,可以在模板层判断数据就绪后再渲染组件内容,同时展示加载态提升用户体验。
<!-- dashboard.component.html --> <ng-container *ngIf="userInfo$ | async as userInfo; else loadingTpl"> <!-- 仪表盘正常内容,可直接使用userInfo --> <div>欢迎回来,{{userInfo.name}}</div> </ng-container> <ng-template #loadingTpl> <!-- 自定义加载中样式 --> <div>数据加载中...</div> </ng-template>
内容的提问来源于stack exchange,提问作者Jay
相关产品推荐
相关产品推荐

