繁体   English   中英

带有 ngrx、AlertController、LoadController 问题的 Ionic 2

[英]Ionic 2 with ngrx, AlertController, LoadController issue

请原谅我的无知,我对反应式概念还很陌生。

我的问题是不知道如何根据商店当前状态加载 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;
}

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

  }

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

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

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

并用一些标签替换 AlertController :

<span>{{errorMessage$ | async}}</span>

暂无
暂无

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

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