1

请原谅我的无知,我对反应性概念相当陌生。

我的问题是不知道如何根据商店当前状态加载 Ionic 2 加载程序或 Ionic 2 警报。

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

任何帮助指出更好的方向,或者我错过了什么,将不胜感激。

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

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

减速器

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

2 回答 2

1

我的商店中只有一个 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;
    }

  }
于 2017-02-14T04:44:35.490 回答
0

我也将 Ionic 2 与 ngrx 一起使用,据我所知,LoadingControllerAlertController不提供任何可观察或承诺。所以我认为你能做的最好的事情就是你现在正在做的事情,订阅它的状态并根据它的状态做一些条件。

或者你可以摆脱 LoadingController 用 ion-spinner 替换它:

<ion-spinner [disabled]="isLoading$ | async"></ion-spinner>

并用一些标签替换 AlertController :

<span>{{errorMessage$ | async}}</span>
于 2017-02-14T04:19:51.560 回答