我从 NGRX/store 获取预订列表,如下所示,数据正确输入,但在页面重新加载时消失。我必须改变路线才能把它拿回来。
ngOnInit() {
this.store.select(state => state.authState.profile).subscribe(profile => {
this.profile = profile;
if (this.profile) {
this.userId = this.profile.$key;
}
});
if (this.userId) {
this.reservations$ = this.reservationService.loadUserReservations(this.userId);
}
}
ngOnChanges() {
if (this.userId) {
this.reservations$ =
this.reservationService.loadUserReservations(this.userId);
}
}
不确定这是否足以说明问题。
在我的身份验证服务中
this.auth$.authState.subscribe(user => {
if (user) {
const userData = user;
const userRef = db.object("users/" + userData.uid);
const dataToSet = {
displayName: userData.providerData[0].displayName,
email: userData.providerData[0].email,
photoURL: userData.providerData[0].photoURL,
providerId: userData.providerData[0].providerId,
registeredAt: new Date()
};
userRef.take(1).subscribe((user) => {
if (user.$exists()) {
// console.log('user exists', user);
this.store.dispatch(this.authActions.updateUserInfo(user));
} else {
// console.log('user does not exists');
userRef.set(dataToSet)
.then((result) => {
// console.log(result)
})
.catch((error) => {
// console.log(error);
});
}
});
// console.log('hello user', user);
this.store.dispatch(this.authActions.loginSuccess(user));
} else {
this.store.dispatch(this.authActions.logOutUser());
}
});
}
我正在使用 Firebase 并订阅 authState 更改。 当用户登录时,我调度一个操作来更新商店,我仅使用 authState.profile 来过滤用户的预订,并且所有工作正常。我在 ngOnInit() 上设置可观察的保留$。
最佳答案
这里有几件事要说。
首先,store 只是一个普通的、内存中的 JavaScript 对象。这意味着页面重新加载就消失了。
其次,如果您需要任何类型的用户身份验证数据的持久性,那么您应该在用户登录时将该数据放入存储中(您已经做了),并另外将其放入某些 localStorage 或 cookie 中。然后,您应该具有读取 localStorage/cookie 以获取身份验证数据并在页面重新加载(或任何页面加载)时重新填充存储的机制。 [这是一个单独的问题,只是为您提供背景信息]
现在,您可能永远不希望发生的一件事是,如果用户未登录(换句话说,如果存储中没有 authState 数据),则用户最终会进入您的预订组件。这正是正在发生的事情。
您有多种选择来解决此问题。一种可能是最好的方法是让 AuthGuard 在 CanActivate 中针对您的预订组件使用的路线运行。
所以,像这样......
检查验证 guard :
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
return this.store.select(yourPartOfStateWhereAuthDataIs)
.map(profileData => !!profileData)
.take(1)
.do(authenticated => {
if (!authenticated) {
this.router.navigate([ 'login' ], {
queryParams: { referer: this.createUrl(route) }
});
}
});
}
然后在您的路由中,用于预订组件路由:
{
path: '',
component: ReservationsComponent,
canActivate: [CheckAuthGuard]
}
这将确保:
- 如果用户最终使用预订组件>则会有 AuthData
- 如果商店中没有 AuthData,当尝试进入预订时 > 用户将被重定向到登录页面
现在,关于预订的另一件事。看来您不是从商店获得预订,而是直接从服务处获得预订。我的建议是实际上为预订组件再设置一名 guard ,这样做是这样的:
- 加载预订(通过调度 ngrx 操作,该操作将调用您已有的服务)
- 当您的商店充满注册数据时,您的 guard 将允许前往预订组件
- 在您的预订组件中,您可以执行
store.select(PartOfStoreWhereReservationsAre)
并从那里使用它们
信息可能有点太多,但我希望您能找到方法;)
关于Angular 2 在页面重新加载时丢失数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45310044/