2017-02-13 11 views
0

Извините мое невежество, я довольно новичок в реактивных концепциях.Ионный 2 с 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; 
} 

ответ

1

Я просто иметь loadingState в моем магазине, а потом я загрузится и выгрузите пользовательский интерфейс spinner/load на основе этого состояния.

У меня есть полный проект здесь, показывающий, как я управлять состоянием и 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

Я использую Ionic 2 с ngrx тоже, и насколько я знаю, LoadingController и AlertController не обеспечивают никаких наблюдаемых или обещаний. Поэтому я думаю, что лучшее, что вы можете сделать, это то, что вы делаете сейчас, подписываясь о своем состоянии и выполняете какое-то условие, основанное на его состоянии.

ИЛИ вы можете избавиться от LoadingController заменить его ионно-блесну:

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

И заменить AlertController с некоторой этикеткой:

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