简体   繁体   English

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

[英]angular 2 losing data on page reload

I get a list of reservations from the NGRX/store like this, the data comes in properly but disappears when the page reloads. 我像这样从NGRX /存储中获取预订列表,数据可以正确输入,但在页面重新加载时会消失。 I have to change routes to get it back. 我必须更改路线才能恢复原状。

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);
      }

  }

not sure if this is enough code to illustrate the problem. 不知道这是否足以说明问题。

in my auth service 在我的身份验证服务中

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());
  }
});

}

I'm using Firebase and subscribing to the authState changes. 我正在使用Firebase并订阅authState的更改。 when the user log ins I dispatch an action to update the store, I'm only using the authState.profile to filter the user's reservations and all the works fine. 当用户登录时,我调度了一个更新商店的操作,我只使用authState.profile来过滤用户的预订,并且所有工作正常。 I'm setting the observable reservations$ on ngOnInit(). 我在ngOnInit()上设置了可观察的Reservations $。

There are several things to say here. 这里有几件事要说。

First of all, store is just a plain, in-memory, javascript object. 首先,store只是一个普通的,内存中的javascript对象。 That means that on page reload its gone. 这意味着页面重新加载已不复存在。

Second, if you need any kind of persistance of user Auth data then you should, upon user logs in, put that data into store (what you already do) and additionally put it into some localStorage or cookie. 其次,如果您需要某种形式的用户Auth数据持久性,则应在用户登录后将该数据放入存储中(您已经执行的操作),并另外将其放入一些localStorage或cookie中。 Then you should have mechanism of reading the localStorage/cookie to get auth data and refill store on page reload (or any page load, for that matter). 然后,您应该具有读取localStorage / cookie的机制,以获取身份验证数据并在页面重新加载(或任何页面加载)时重新填充存储。 [This is a separate issue, just givin you context] [这是一个单独的问题,请您根据具体情况提供]

Now, one thing you probably never want ot happen is that user ends up on your reservations component if he is not logged in (in other words, if there are no authState data in store). 现在,您可能永远不想发生的一件事是,如果用户未登录(例如,如果存储中没有authState数据),该用户最终将进入预订组件。 And that is exactly what is happening. 而这正是正在发生的事情。

You have several options to solve this. 您有几种解决方案。 One, probably best, is to have AuthGuard that will run in CanActivate for the route that your reservation component uses. 一种可能是最好的方法是拥有AuthGuard,它将在CanActivate中针对您的预订组件使用的路由运行。

So, something like this... 所以像这样

CheckAuthGuard: 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) }
          });
        }
      });
    }

and then in your routing, for reservations component route: 然后在您的路由中,对于保留组件路由:

{
  path: '',
  component: ReservationsComponent,
  canActivate: [CheckAuthGuard]
}

this will ensure that: 这将确保:

  1. if user ends up on reservations component > there is AuthData 如果用户最终进入预订组件>有AuthData
  2. if there is no AuthData in store, when attempting to go to reservations > user will get redirected to login page 如果存储中没有AuthData,则尝试转到预订时>用户将被重定向到登录页面

Now, one additional thing about getting reservations. 现在,关于预订的另一件事。 Seems like you are not getting reservations from store but from service directly. 似乎您不是从商店获得预订,而是直接从服务获得预订。 What i'd suggest is to actually put one more guard, for Reservations component and there do: 我的建议是实际上为保留部分再增加一个警卫,然后这样做:

  1. Load Reservations (through dispatching ngrx action which will in turn call service you already have) 负载预留(通过调度ngrx操作,这将依次调用您已经拥有的服务)
  2. When your store is filled with Registration data, then your guard will allow going to Reservations component 当您的商店中充满了注册数据时,您的门卫将允许进入预订部分
  3. in your reservations component you would do store.select(PartOfStoreWhereReservationsAre) and use them from there 在预订组件中,您将进行store.select(PartOfStoreWhereReservationsAre)并从那里使用

It might be a bit too many infos but i hope you'll find your way through it ;) 可能有太多的信息,但我希望您能通过它找到方法;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM