【问题标题】:Angular data loss on reload using BehaviorSubject使用 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,使用它。否则将用户导航回登录组件

标签: angular service reload behaviorsubject data-loss


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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 2018-11-20
      • 1970-01-01
      相关资源
      最近更新 更多