请原谅我的无知,我对反应式概念相当陌生。
我的问题是不知道如何处理加载 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;
}
我的商店中只有一个 loadState,然后我根据该状态加载和卸载微调器/加载 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 一起使用,据我所知,LoadController 和 AlertController 不提供任何可观察或承诺。所以我认为你能做的最好的事情就是你现在正在做的事情,订阅它的状态,并根据它的状态做一些条件。
或者你可以摆脱加载控制器用离子旋转器替换它:
<ion-spinner [disabled]="isLoading$ | async"></ion-spinner>
并将警报控制器替换为一些标签:
<span>{{errorMessage$ | async}}</span>