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());
}
我正在使用数据服务将用户数据发送到应用程序并在我的 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());
}