【问题标题】:Ionic 2 with ngrx, AlertController, LoadController issue带有ngrx,AlertController,LoadController问题的Ionic 2
【发布时间】:2017-02-13 15:33:45
【问题描述】:

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

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

【问题讨论】:

    标签: javascript angular ionic2 ngrx ngrx-effects


    【解决方案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;
        }
    
      }
    

    【讨论】:

    • 我采用了与此类似的解决方案。我的主要问题是,效果似乎不会冒泡捕获的错误。虽然我认为这个问题是一个变更检测问题。
    【解决方案2】:

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

    或者你可以去掉 LoadingController 用 ion-spinner 替换它:

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

    并用一些标签替换 AlertController :

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      • 2018-08-05
      • 2017-07-09
      相关资源
      最近更新 更多