2017-02-13 32 views
0

請原諒我的無知,我是相當新的反應性概念。Ionic 2與ngrx,AlertController,LoadController問題

我的問題是不知道如何處理根據商店當前狀態加載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; 
} 

回答

1

我只是有一個LoadingState進行在我的商店,然後我打開並根據該狀態卸載微調器/加載用戶界面。

我這裏有一個完整的項目展示我如何管理國家和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; 
    } 

    } 
+0

我有一個類似的解決方案說幹就幹。我的主要問題在於,似乎效果不會引起捕獲的錯誤。雖然我認爲這個問題是一個變化檢測問題。 –

0

我用ngrx也使用Ionic 2,據我所知,LoadingControllerAlertController不提供任何可觀察或承諾。所以我認爲你可以做的最好的是你現在正在通過訂閱它的狀態並根據它的狀態做一些條件。

或者你可以擺脫LoadingController用離子微調替換:

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

而且與某些標籤替換AlertController:

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