Angular 使用 BehaviorSubject 重新加载时数据丢失

Angular data loss on reload using BehaviorSubject

我正在使用数据服务将用户数据发送到应用程序并在我的 header 组件中显示用户名。如果我使用登录组件登录我的应用程序,用户名会正确显示,但当我重新加载页面时,用户数据会消失。

登录时重新加载前

重新加载后

用户数据来自使用 BehaviorSubject 的数据服务:

data.service.ts

    export class DataService {
    
      private userSource = new BehaviorSubject({});
      currentUser = this.userSource.asObservable().pipe(distinctUntilChanged());
    
      constructor(private injector: Injector, private api: UtentiApiService) { }
    
      getUser() {
        return this.currentUser;
      }
    
      getUserFromToken() {
        const authService = this.injector.get(AuthService);
        const token = authService.getToken();
        const userIdToken = jwt_decode(token);
        // console.log(userIdToken);
        return this.api.getUtente(userIdToken.userId);
      }
    
      getPermissionsFromToken(): Observable<any> {
        const authService = this.injector.get(AuthService);
        const token = authService.getToken();
        const userIdToken = jwt_decode(token);
    
        return of(userIdToken.permArr);
      }
      changeUser(user: object) {
        this.userSource.next(user);
      }
    
    }

在 header 组件中我消费了服务:

header.component.ts

    export class HeaderComponent implements OnInit {
      user: object;
    
      constructor(private router: Router, private authService: AuthService, private data: DataService) { }
    
    
      ngOnInit() {
        this.getUser();
      }
    
      getUser() {
        this.data.getUser().subscribe(utente => {
          this.user = utente;
          console.log(this.user);
        });
      }
    
      onLogout() {
        this.authService.logoutUser();
      }
    
      sendUser(user) {
        this.data.changeUser(user);
      }
    }

在登录组件中,我将用户数据发送到数据服务,但在重新加载时未触发登录组件,因此我在服务和 header 中都没有用户数据。我该如何修复这个错误?

这里是一个包含完整代码的 stackblitz:https://stackblitz.com/github/ufollettu/SEANSA

感谢您的帮助

来自您的代码:

private userSource = new BehaviorSubject({});
  currentUser = this.userSource.asObservable().pipe(distinctUntilChanged());

  constructor(private injector: Injector, private api: UtentiApiService) { }

  getUser() {
    return this.currentUser;
  }

您的 userSource 是一个 BehaviorSubject,当您启动您的应用程序时(也包括重新加载),它不包含任何内容。

当您登录用户时,您调用:

changeUser(user: object) {
    this.userSource.next(user);
  }

在此调用之后,您的 BehavoirSubject 包含一个用户。但是您只能在登录过程中执行此操作。

当您重新加载页面时,您需要从本地存储中获取访问令牌,然后在当前用户的 BehavoirSubject 上调用 next。

例如,您可以在数据服务的构造函数中执行此操作。

使用 SessionStorage 或 localStorage 或 cookie 来存储您的数据。

当您点击刷新时,将您的数据复制到上述任何存储中,并在初始化时将其复制回您的变量中。 检查下面的例子。将sessionStorage替换为localStorage,将数据存储在localStorage中。

在 AppComponent 中

    ngOnInit() {
    if (sessionStorage.getItem("user")) {
      this.data.changeUser(sessionStorage.getItem("user"));
    }
      }
@HostListener('window:beforeunload', ['$event'])
      unloadNotification($event: any) {
        sessionStorage.setItem("user", this.getUser());
      }