javascript - Ionic 2 与 ngrx、AlertController、LoadController 问题

标签 javascript angular ionic2 ngrx ngrx-effects

请原谅我的无知,我对响应式(Reactive)概念还很陌生。

我的问题是不知道如何根据存储当前状态处理加载 Ionic 2 加载器或 Ionic 2 警报。

我已经能够通过订阅它所响应的存储切片来实现我需要的加载器行为。尽管当涉及到警报(因捕获的错误而引发)时,它永远不会在订阅 block 中触发。

任何帮助指出更好的方向或我错过的内容将不胜感激。

此代码来自登录模态视图。

signin(user) {
    this.submitAttempt = true;

    if (this.signinForm.valid) {
        let loader = this.loadingCtrl.create({
            content: "Signing In..."
        });

        let auth;
        let signinSub = this.store.select(s => auth = s.auth).subscribe(() => {
            if (auth.state) {
                loader.dismiss();
            } else if (auth.error) {
                let alert = this.alertCtrl.create({
                    title: "Error",
                    subTitle: auth.error,
                    buttons: ['OK']
                });
                loader.dismiss();
                alert.present();
            }
        });

        loader.present();
        this.store.dispatch(UserActions.UserActions.signinUser(user));
    }
}

效果

@Effect() signinUser$ = this.actions$
.ofType(UserActions.ActionTypes.SIGNIN_USER)
.map(toPayload)
.switchMap(user => {
    return Observable.fromPromise(this.userService.signinUser(user))
        .map(result => {
            return ({ type: "GET_USER", payload: user});
        })
        .catch(err => {
            return Observable.of({ type: "SIGNIN_USER_FAILED", payload: err });
        });
});

服务

signinUser(user): Promise<any> {
    return <Promise<any>>firebase.auth()
    .signInWithEmailAndPassword(user.email, user.password);
}

reducer

export const UserReducer: ActionReducer<Auth> = (state: Auth = initialState, action: Action) => {
    switch(action.type) {
        case UserActions.ActionTypes.SIGNIN_USER:
            return state;
        case UserActions.ActionTypes.SIGNIN_USER_FAILED:
            return Object.assign(state, { apiState: "Failed", error: action.payload.message });
        case UserActions.ActionTypes.STARTED_SIGNIN:
            return Object.assign(state, { requested: true });
        case UserActions.ActionTypes.GET_USER:
            return Object.assign(state, { apiState: "Success", error: ""});
        case UserActions.ActionTypes.GET_USER_SUCCESS:
            return Object.assign({ user: action.payload.val() }, state, { state: true });
        default:
            return state;
    };
}

商店

export interface Auth {
    state: boolean,
    requested: boolean,
    apiState: string,
    error: {},
    user?: {}
}

export interface AppState {
    auth: Auth;
}

最佳答案

我的商店中只有一个 loadingState,然后我根据该状态加载和卸载微调器/加载 UI。

我这里有一个完整的项目,展示了我如何管理状态和 UI

https://github.com/aaronksaunders/ngrx-simple-auth

/**
 * Keeping Track of the AuthenticationState
 */
export interface AuthenticationState {
  inProgress: boolean;            // are we taking some network action
  isLoggedIn: boolean;            // is the user logged in or not
  tokenCheckComplete: boolean;    // have we checked for a persisted user token
  user: Object;                   // current user | null
  error?: Object;                 // if an error occurred | null

}

然后在不同的状态下,AuthActions.LOGIN

case AuthActions.LOGIN: {
  return Object.assign({}, state, {inProgress: true, isLoggedIn: false, error: null})

}

然后,AuthActions.LOGIN_SUCCESS

case AuthActions.LOGIN_SUCCESS: {
  return Object.assign({}, state, {inProgress: false, user: action.payload, isLoggedIn: true})
}

这是我们在LoginPage中处理它的方式

    var dispose = this.store.select('authReducer').subscribe(
      (currentState: AuthenticationState) => {
        console.log("auth store changed - ", currentState);
        if (currentState.user) {
          dispose.unsubscribe();
          this.nav.setRoot(HomePage, {});
        }

        // this is where the magic happens...
        this.handleProgressDialog(currentState);

        this.error = currentState.error
      },
      error => {
        console.log(error)
      }
    );

  }

我们如何处理加载

  /**
   *
   * @param _currentState
   */
  handleProgressDialog(_currentState) {
    if (_currentState.inProgress && this.loading === null) {
      this.loading = this.loadingCtrl.create({
        content: "Logging In User..."
      });
      this.loading.present()
    }


    if (!_currentState.inProgress && this.loading !== null) {
      this.loading && this.loading.dismiss();
      this.loading = null;
    }

  }

关于javascript - Ionic 2 与 ngrx、AlertController、LoadController 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42207774/

相关文章:

javascript - 重构此方法以将其认知复杂度从 21 降低到允许的 15。如何重构和降低复杂度

angular - 如何将项目数据传递给 angular 2 的单击事件?

javascript - jquery spinner加载后如何加载body内的内容

javascript - React - 在 child 中设置状态?

Angular 2 - 无法绑定(bind)到 'controlGroup',因为它不是 'div' 元素的已知属性

arrays - ionic 2/3 : Number Input from Alert

angular - 如何从 IONIC 3 中的图库中获取或选择图像

javascript - jQuery 1.4.2 IE8 页面出现错误,预期为 ')'

javascript - 执行 onkeydown 时捕获之前的值

Angular 6 with Material,点击事件无法正常工作