Маршрутизация между двумя компонентами удаляет подписку из хранилища NGRX - PullRequest
0 голосов
/ 01 мая 2020

В моем приложении две страницы Dashboard и Transactions и компонент Sidebar, который управляет навигацией.

При первом переходе от Dashboard к Transactions я подписываюсь на состояние пользователя в моем магазине. Все работает, как и ожидалось, я получаю userID и вставляю его в дочерние компоненты для использования.

export class TransactionsComponent implements OnInit {
  userID;

  constructor(private store: Store<AppState>, private spinner: NgxSpinnerService) {}

  ngOnInit() {
    this.spinner.show();
    this.store.select('user').subscribe(
      user => { if (user) { this.userID = user.uid; } }
    );
  }
}

Когда я возвращаюсь на страницу Dashboard и затем обратно на страницу Transactions, с которой я застрял ID пользователя никогда не разрешается и бесконечный спиннер загрузки.

В моей Sidebar эта подписка исчезает при переходе со страницы транзакций на панель инструментов.

export class SidebarComponent implements OnInit {
  user$: Observable<User>;

  constructor(public auth: AuthService, private store: Store<AppState>) {}

  ngOnInit(): void {
    this.user$ = this.store.select('user');
    this.store.dispatch(new userActions.GetUser());
  }
}

Вот мой эффект, который будет получить идентификатор пользователя

  @Effect()
  getUser: Observable<Action> = this.actions.pipe(
    ofType(userActions.GET_USER),
    map((action: userActions.GetUser) => action.payload ),
    switchMap(payload => this.afAuth.authState),
    delay(2000), // delay to show loading spinner can be deleted
    map( authData => {
        if (authData) {
          // User logged in
          const user = new User(authData.uid, authData.displayName);
          return new userActions.Authenticated(user);
        } else {
          return new userActions.NotAuthenticated();
        }
    }),
    catchError(err => of(new userActions.AuthError()) )
  );

Я ожидаю, что компонент Transactions сохранит состояние идентификатора пользователя и не потребует загрузки счетчика при переходе назад.

1 Ответ

0 голосов
/ 05 мая 2020

У вас есть правильный код в SidebarComponent с user$ - просто создайте Observable вместо subscription.

В TransactionsComponent вам нужно использовать тот же шаблон, есть ли причина сохранить пользователя userID в качестве независимого свойства?

Я бы предложил вам следующий подход.

export class TransactionsComponent implements OnInit {
  userId$;

  constructor(private store: Store<AppState>, private spinner: NgxSpinnerService) {}

  ngOnInit() {
    this.userId = this.store.select('user').pipe(
      tap(user => {
        if (user) { // we've got a use, the data has been loaded
          this.spinner.hide();
        } else {
          this.spinner.show(); // no user - looks like the loading is in progress
        }
      }),
      map(user => user ? user.uid : undefined),
      filter(userId => userId !== undefined), // <- comment in case userId isn't required.
    );
  }
}

и затем в его шаблоне

<ng-container *ngIf="userId$ | async as userId">
   <child-component [userId]="userId"></child-component>
</ng-container>
...