@ngrx:创建后调用存储的订阅

时间:2017-03-09 15:08:14

标签: angular rxjs ngrx

我的IStore就像:

export interface IStore {
  user: IUser;
  sources: ISourceRedux;
}

LoginComponent我订阅了IStore.user

private user$: Observable<IUser>;
private userSub: Subscription;
constructor(private store$: Store<IStore>)
{
    this.user$ = this.store$.select(state => state.user);
}

ngOnInit():void {
    this.userSub = this.user$.subscribe(
        (user: IUser) => {
            this.router.navigate(['/app']);
        },
        (error: any) => {
            this.addAlert(error.message);
        }
    );
}

问题在于&#34;订阅被称为&#34;一旦它刚刚创建。

有什么想法吗?

我有这些影响:

@Injectable()
export class UserEffects {
  constructor(
    private _actions$: Actions,
    private _store$: Store<IStore>,
    private _userService: UsersService,
  ) { }

  @Effect({ dispatch: true })
  userLogin$: Observable<Action> = this._actions$
    .ofType('USER_REDUCER_USER_LOGIN')
    .switchMap((action: Action) =>
      this._userService.checkPasswd(action.payload.username, action.payload.password)
        .map((user: any) => {
          return { type: 'USER_REDUCER_USER_LOGIN_SUCCESS', payload: user };
        })
        .catch((err) => {
          return Observable.of({ type: 'USER_REDUCER_USER_LOGIN_FAILED', payload: { error: err } });
        })
    );
}

和redurs:

export class UserReducer {
  private static reducerName = 'USER_REDUCER';

  public static reducer(user = initialUserState(), {type, payload}: Action) {
    if (typeof UserReducer.mapActionsToMethod[type] === 'undefined') {
      return user;
    }

    return UserReducer.mapActionsToMethod[type](user, type, payload);
  }

    // tslint:disable-next-line:member-ordering
    /**
     * Default reducer type. I want all sources.
     */
    public static USER_LOGIN = `${UserReducer.reducerName}_USER_LOGIN`;

    /**
     * User login success.
     */
    public static USER_LOGIN_SUCCESS = `${UserReducer.reducerName}_USER_LOGIN_SUCCESS`;
    private static userLoginSuccess(sourcesRdx, type, payload) {
        return Object.assign(<IUser>{}, sourcesRdx, payload);
    }

    /**
     * User login fails.
     */
    public static USER_LOGIN_FAILED = `${UserReducer.reducerName}_USER_LOGIN_FAILED`;
    private static userLoginFailed(sourcesRdx, type, payload) {
        return Object.assign(<IUser>{}, sourcesRdx, payload);
    }

  // ---------------------------------------------------------------

  // tslint:disable-next-line:member-ordering
  private static mapActionsToMethod = {
      [UserReducer.USER_LOGIN_SUCCESS]: UserReducer.userLoginSuccess,
      [UserReducer.USER_LOGIN_FAILED]: UserReducer.userLoginFailed,
  };
}

1 个答案:

答案 0 :(得分:2)

您可以尝试:

this.user$
  .skip(1)
  .subscribe(...)

如果这是用户在商店中初始化的唯一地方。如果这不起作用,你可以尝试其他几个运营商等待&#39;对某事......

this.user$
  .filter(user => user !== "some_inital_different_from_logout_state"
  .subscribe(...)

或将ready标志添加到商店

this.user$
  .skipUntil(this.store.select('ready'))
  .subscribe(...)

更新(说明):

当商店初始化并且它触发第一次更新时,将调度操作@ngrx/store/init,因为如果操作不匹配,则所有reducer都会返回状态树的一部分:

export function someReducer(state: any, action: Action): any {
  switch (action.type) {
    default:
      return state;
  }
}