角度2在页面重新加载时丢失数据

时间:2017-07-25 17:29:22

标签: angular ngrx-store

我从NGRX /商店获得这样的预订列表,数据正确,但在页面重新加载时消失。我必须改变路线以取回它。

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()上设置了observable reservations $。

1 个答案:

答案 0 :(得分:2)

这里有几点要说。

首先,store只是一个简单的内存中的javascript对象。这意味着页面重新加载它已经消失了。

其次,如果您需要任何持久的用户Auth数据,那么您应该在用户登录后将该数据存入商店(您已经做过的事情),并将其添加到某个localStorage或cookie中。然后你应该有读取localStorage / cookie的机制来获取auth数据并在页面重新加载时重新填充存储(或任何页面加载,就此而言)。 [这是一个单独的问题,只是给你上下文]

现在,您可能永远不会想要的一件事是,如果用户未登录,则用户会在您的预订组件上结束(换句话说,如果商店中没有authState数据)。而这正是发生的事情。

您有几种方法可以解决这个问题。最好的一种方法是让AuthGuard在CanActivate中运行,用于预订组件使用的路线。

所以,像这样......

CheckAuthGuard:

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]
}

这将确保:

  1. 如果用户在预订组件上结束&gt;有AuthData
  2. 如果商店中没有AuthData,则在尝试进入预订时&gt;用户将被重定向到登录页面
  3. 现在,还有一个关于获得预订的事情。好像你没有从商店预订,而是从服务直接预订。我建议的是实际再添加一个后卫,对于预订组件而言:

    1. 加载预订(通过调度ngrx操作,该操作将依次调用您已有的服务)
    2. 当您的商店注册了注册数据时,您的警卫将允许进入预订组件
    3. 在您的预订组件中,您可以store.select(PartOfStoreWhereReservationsAre)并从那里使用
    4. 可能有点太多的信息,但我希望你能找到自己的方式;)

相关问题