我喜欢官方指南 由ngrx. 我想为我的第一个商店对象创建 auth
. 我想,我可以更好地理解逻辑,提高自己的技能,如果我从 logout
逻辑。
作为零步骤,我为http请求创建服务 http-auth.service.ts
:
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { throwError, Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { environment } from 'environments/environment';
import { RegistrationModel } from 'app/shared/models';
import { TextSuccessModel } from 'app/shared/models/common';
@Injectable()
export class HttpAuthService {
constructor(private http: HttpClient) {}
$logout(): Observable<TextSuccessModel> {
// @FIXME: post request
return this.http.get(`${environment.apiUrl}/auth/logout`).pipe(
map((response: TextSuccessModel) => response),
catchError(this.handleError())
);
}
private handleError<T>() {
return (error: HttpErrorResponse) => {
return throwError(error.message || 'Something went wrong');
};
}
}
我创造了 actions
分档 actions/auth.actions.ts
:
import { createAction } from '@ngrx/store';
// logout
export const logout = createAction('[Auth] Logout request');
export const logoutSuccess = createAction('[Auth] Logout Success');
export const logoutError = createAction('[Auth] Logout Fail');
接下来,我创建了 reducer
在 reducers/auth.reducer.ts
:
import { Action, createReducer, on } from '@ngrx/store';
import * as AuthActions from '../actions/auth.actions';
export interface AuthState {
id: string | null;
rememberMe: boolean;
}
export const initialState: AuthState = {
id: null,
rememberMe: false,
};
export const authReducer = createReducer(
initialState,
// logout
on(AuthActions.logout, (state) => ({
...state,
loading: true,
})),
on(AuthActions.logoutSuccess, () => initialState),
on(AuthActions.logout, () => initialState)
);
export function reducer(state: AuthState | undefined, action: Action) {
return authReducer(state, action);
}
接下来我为商店创建模块
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';
import { RouterModule } from '@angular/router';
import { effects } from './effects';
import { reducers } from './reducers';
@NgModule({
imports: [
CommonModule,
HttpClientModule,
StoreModule.forFeature('entityCache', reducers),
EffectsModule.forFeature(effects),
RouterModule,
],
exports: [StoreModule, EffectsModule],
})
export class AppStoreModule {}
最后,我试着创造一个效果 auth.effects.ts
:
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Observable, of } from 'rxjs';
import { exhaustMap, tap, catchError } from 'rxjs/operators';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { HttpAuthService } from 'app/services/http';
import { TextSuccessModel } from 'app/shared/models/common';
import * as AuthActions from '../actions/auth.actions';
@Injectable()
export class AuthEffects {
constructor(
private actions$: Actions,
private router: Router,
private httpAuthService: HttpAuthService
) {}
/**
* LOGOUT
*/
logout$ = createEffect(() => {
return this.actions$.pipe(
ofType(AuthActions.logout),
exhaustMap(() => {
return this.httpAuthService.$logout().pipe(
tap(() => AuthActions.logoutSuccess()),
catchError(() => of(AuthActions.logoutError()))
);
})
);
});
}
而且vscode把我的代码标记为错误。
function(): Observable<TextSuccessModel | TypedAction<"[Auth] Logout Fail">>
Argument of type '() => Observable<TextSuccessModel | TypedAction<"[Auth] Logout Fail">>' is not assignable to parameter of type '() => Observable<Action> | ((...args: any[]) => Observable<Action>)'.
Type 'Observable<TextSuccessModel | TypedAction<"[Auth] Logout Fail">>' is not assignable to type 'Observable<Action> | ((...args: any[]) => Observable<Action>)'.
Type 'Observable<TextSuccessModel | TypedAction<"[Auth] Logout Fail">>' is not assignable to type 'Observable<Action>'.
I'm new in angular. 我找到了旧版angular创建type对象的解决方案。但我不明白如何解决这个问题。请帮助我。
一个效果应该总是返回一个动作(除非它被标记为dispatch false)。
tap操作符,不返回一个值,因为它是一个void.你应该使用一个map来返回成功的操作。
logout$ = createEffect(() => {
return this.actions$.pipe(
ofType(AuthActions.logout),
exhaustMap(() => {
return this.httpAuthService.$logout().pipe(
map(() => AuthActions.logoutSuccess()),
catchError(() => of(AuthActions.logoutError()))
);
})
);
});