使用 BehaviorSubject 重新加载时的角度数据丢失

Posted

技术标签:

【中文标题】使用 BehaviorSubject 重新加载时的角度数据丢失【英文标题】:Angular data loss on reload using BehaviorSubject 【发布时间】:2019-01-15 12:05:48 【问题描述】:

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

登录时重新加载之前

重新加载后

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

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

这里有完整代码的堆栈闪电战:https://stackblitz.com/github/ufollettu/SEANSA

感谢您的帮助

【问题讨论】:

这不正是我们有会话管理概念的原因吗?所以基本上在登录时你必须将数据存储在localStorage中。在组件初始化时,您检查 localStorage 中是否有 userData,使用它。否则将用户导航回登录组件 【参考方案1】:

使用 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());
      

【讨论】:

【参考方案2】:

来自您的代码:

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 的构造函数中执行此操作。

【讨论】:

以上是关于使用 BehaviorSubject 重新加载时的角度数据丢失的主要内容,如果未能解决你的问题,请参考以下文章

使用 next.js 和样式化组件重新加载时的 Flash Of Unstyled Text (FOUT)

重新加载包含 UITableView 的 UIViewController 时的 EXEC_BAD_ACCESS

从集合视图重新加载数据时的多个视图

Django:jQuery触发表单提交onchange of checkbox并保留重新加载时的值

UITableView 重新加载部分时的内容插入更改

如何在 HTMX 中重新加载页面刷新时的所有部分