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

标签 angular ngrx-store

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

这将确保:

  1. 如果用户最终使用预订组件>则会有 AuthData
  2. 如果商店中没有 AuthData,当尝试进入预订时 > 用户将被重定向到登录页面

现在,关于预订的另一件事。看来您不是从商店获得预订,而是直接从服务处获得预订。我的建议是实际上为预订组件再设置一名 guard ,这样做是这样的:

  1. 加载预订(通过调度 ngrx 操作,该操作将调用您已有的服务)
  2. 当您的商店充满注册数据时,您的 guard 将允许前往预订组件
  3. 在您的预订组件中,您可以执行 store.select(PartOfStoreWhereReservationsAre) 并从那里使用它们

信息可能有点太多,但我希望您能找到方法;)

关于Angular 2 在页面重新加载时丢失数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45310044/

相关文章:

使用 NgRx store 进行 Angular 内存优化以避免内存泄漏

css - Angular 在全局 style.css 文件中使用 CSS 变量

angular - 使用 ngrx store 与 @Input 进行通信之间的简单通信

Ngrx 存储出现错误,因为类型上不存在属性 'ofType'

angular - NGRX Redux 存储——仅选择状态的一部分返回 'undefined',即使智能感知自动完成并且模型中的所有内容都匹配

angular - Angular2 中 $templateCache 的替代品

angular - 如果条件在 RxJS 中为真,我可以跳过所有后续运算符链吗

Angular ngrx@effect 基本问题 : Type 'Observable<void>' is not assignable to type

angular - 使用 Jasmine 在 Angular 8 中测试异步代码时如何等待?

angular - 在 Angular2 中使用 nativeElement 访问 DOM 有哪些好的替代方法?