我想要为我使用rxjs的效果进行http调用。现在我的问题是我想在http调用之前发送另一个像{ type: LoaderActions.LOADER_START }
的动作。因此,当请求Http调用时,用户可以看到加载屏幕,一旦请求完成,我想发送另一个动作{ type: LoaderActions.LOADER_END }
。
如何使用rxjs运算符实现此目的?我很困惑何时在rxjs中使用哪个运算符。
auth.effects.ts
import { Injectable } from '@angular/core';
import { Observable, of, concat } from 'rxjs';
import { Action, Store } from '@ngrx/store';
import { Actions, Effect, ofType } from '@ngrx/effects';
import * as AuthActions from './auth.actions';
import * as LoaderActions from '../../loader/store/loader.actions';
import {
map,
mergeMap,
switchMap,
debounce,
debounceTime,
tap,
startWith
} from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Router } from '@angular/router';
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json; charset=utf-8'
})
};
@Injectable()
export class AuthEffects {
@Effect()
signInAction$: Observable<Action> = this.actions$.pipe(
ofType(AuthActions.TRY_SIGN_IN),
mergeMap(action =>
this.http
.post(
'http://localhost:8081/auth',
JSON.stringify({
username: action['username'],
password: action['password']
}),
httpOptions
)
.pipe(
map(data => {
if (data['message'] === 'successs') {
this.router.navigate(['/todo']);
return { type: AuthActions.SET_AUTH_FLAG, payload: true };
} else {
return { type: AuthActions.SET_AUTH_FLAG, payload: false };
}
})
)
)
);
constructor(
private actions$: Actions,
private http: HttpClient,
private router: Router
) {}
}
您可以使用concat
,其中第一个源Observable将是加载操作。
@Effect()
signInAction$: Observable<Action> = this.actions$.pipe(
ofType(AuthActions.TRY_SIGN_IN),
concatMap(action => concat(
of({ type: LoaderActions.LOADER_START }),
this.http...
of({ type: LoaderActions.LOADER_END }),
))
)
concat
操作符将确保按顺序创建操作。
您应该为ofType(AuthActions.TRY_SIGN_IN)
创建更多效果侦听器并将此动作映射到发出{ type: LoaderActions.LOADER_START }
。然后,在您提供的效果中,您应该这样做
switchMap(data => {
if (data['message'] === 'successs') {
this.router.navigate(['/todo']);
return [{ type: AuthActions.SET_AUTH_FLAG, payload: true }, { type: LoaderActions.LOADER_END }];
} else {
return [{ type: AuthActions.SET_AUTH_FLAG, payload: false }, { type: LoaderActions.LOADER_END }];
}
})
使用这种方法,您将获得所需的行为:加载器操作和http请求同时执行,当http请求完成时,它将发出操作以设置auth标志并删除加载程序
您不应该为您的目的使用额外的操作。只需将loading: boolean
属性添加到您的州并默认设置为false
。当您发送TRY_SIGN_IN
时,您可以将其设置为减速器中的true
。当http到达成功或失败时,您可以通过发送SET_AUTH_FLAG
操作再次将加载状态设置为false。
然后你可以用适当的选择器选择加载状态,但我猜你知道我的意思,并在模板中使用Angulars async
管道。