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

11

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

在重新加载之前登录

输入图像描述 输入图像描述

重新加载后

输入图像描述 输入图像描述

用户数据来自使用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.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);
      }
    }

在登录组件中,我将用户数据发送到数据服务,但是在重新加载页面时,登录组件不会被触发,因此我在服务中或标题中都没有用户数据。如何修复这个错误?

这里是带有完整代码的 StackBlitz:https://stackblitz.com/github/ufollettu/SEANSA

感谢您的帮助。


这不正是我们拥有会话管理概念的原因吗?因此,基本上在登录时,您必须将数据存储在localStorage中。在组件初始化时,检查localStorage中是否有userData,如果有,则使用它。否则,将用户导航回登录组件。 - Vinod Bhavnani
2个回答

9

使用SessionStorage、localStorage或cookies来存储数据。

当您刷新页面时,将您的数据复制到上述任何存储中,在初始化后将其复制回变量中。 请参考下面的示例。将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());
      }

6

从您的代码:

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将包含一个用户。但是,您只能在登录过程中执行此操作。

当您重新加载页面时,您需要从localstorage获取访问令牌,并使用当前用户对BehavoirSubject调用next。

例如,在dataService的构造函数中可以这样做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接