使用BehaviorSubject

时间:2018-08-08 09:23:34

标签: angular service reload behaviorsubject data-loss

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

登录后重新加载

enter image description here enter image description here

重新加载后

enter image description here enter image description here

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

谢谢您的帮助

2 个答案:

答案 0 :(得分:3)

从您的代码中:

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的构造函数中做到这一点。

答案 1 :(得分:3)

使用SessionStorage或localStorage或cookie存储数据。

单击刷新后,将数据复制到上述任何存储中,并在init上将其复制回变量中。 检查以下示例。将sessionStorage替换为localStorage,以将数据存储在localStorage中。

在AppComponent中

def labeller(labels):
    value = [0] * max_label
    for label in labels:
        value[int(label[-1])-1] = 1
    return value

df['labels'] = df['labels'].apply(lambda x: x.split(", ")).apply(labeller)

df[['label_' + str(i+1) for i in range(max_label)]] = df.labels.apply(pd.Series)
df.drop(['labels'], axis=1, inplace=True)

    text    label_1 label_2 label_3 label_4 label_5
0   abcd    1       1       0       0       0
1   efgh    1       1       1       0       0
2   ijkl    0       1       0       1       0
3   mnop    1       1       0       0       1
4   qrst    0       1       1       0       0
5   uvwx    1       1       1       0       1
6   yz      1       0       1       0       0