angular - 使用 NgRx 和拦截器的循环依赖警告
问题描述
我在我的拦截器中添加了一个调度来检查用户令牌是否过期以将它们注销,但由于某种原因,我收到了很多关于循环依赖的警告。
// Angular
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse } from '@angular/common/http';
import { NavigationEnd, Router } from '@angular/router';
// RxJS
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
// import { debug } from 'util';
// NGRX
import { Store } from '@ngrx/store';
// State
import { AppState } from '../../../../core/reducers';
import { Logout } from '../../../../core/auth/';
@Injectable()
export class InterceptService implements HttpInterceptor {
constructor(private store: Store<AppState>) {}
// intercept request and add token
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
// tslint:disable-next-line:no-debugger
// modify request
request = request.clone({
setHeaders: {
Authorization: `${localStorage.getItem('authToken')}`
}
});
// console.log('----request----');
// console.log(request);
// console.log('--- end of request---');
return next.handle(request).pipe(
tap(
event => {
if (event instanceof HttpResponse) {
// console.log('all looks good');
// http response status code
console.log(event.status);
}
},
error => {
// http response status code
// console.log('----response----');
// console.error('status code:');
// tslint:disable-next-line:no-debugger
// console.error(error.status);
console.error(error.error.error);
if (error.error.error !== undefined && error.error.error.includes('Expired Token')) {
alert('You have been logged out due to signing in from another');
this.store.dispatch(new Logout());
}
// console.log('--- end of response---');
}
)
);
}
}
代码可以正常工作,但我不知道我是否应该意识到这些问题。我在注销组件上使用了完全相同的结构,并且没有问题。我假设是因为它是一项服务?
// auth.effect.ts
// Angular
import { Injectable } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
// RxJS
import { filter, mergeMap, tap, withLatestFrom } from 'rxjs/operators';
import { defer, Observable, of } from 'rxjs';
// NGRX
import { Actions, Effect, ofType } from '@ngrx/effects';
import { Action, select, Store } from '@ngrx/store';
// Auth actions
import { AuthActionTypes, Login, Logout, Register, UserLoaded, UserRequested } from '../_actions/auth.actions';
import { AuthService } from '../_services/index';
import { AppState } from '../../reducers';
import { environment } from '../../../../environments/environment.prod';
import { isUserLoaded } from '../_selectors/auth.selectors';
@Injectable()
export class AuthEffects {
@Effect({dispatch: false})
logout$ = this.actions$.pipe(
ofType<Logout>(AuthActionTypes.Logout),
tap(() => {
localStorage.removeItem(environment.authToken);
this.router.navigate(['/auth/login'], {queryParams: {returnUrl: this.returnUrl}});
})
);
private returnUrl: string;
constructor(private actions$: Actions,
private router: Router,
private auth: AuthService,
private store: Store<AppState>) {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
this.returnUrl = event.url;
}
});
}
}
//auth.reducer.ts
// Actions
import { AuthActions, AuthActionTypes } from '../_actions/auth.actions';
// Models
import { User } from '../_models/user.model';
export interface AuthState {
loggedIn: boolean;
authToken: string;
user: User;
isUserLoaded: boolean;
}
export const initialAuthState: AuthState = {
loggedIn: false,
authToken: undefined,
user: undefined,
isUserLoaded: false
};
export function authReducer(state = initialAuthState, action: AuthActions): AuthState {
switch (action.type) {
case AuthActionTypes.Logout:
return initialAuthState;
default:
return state;
}
}
//auth.actions.ts
import { Action } from '@ngrx/store';
import { User } from '../_models/user.model';
export enum AuthActionTypes {
Logout = '[Logout] Action'
}
export class Logout implements Action {
readonly type = AuthActionTypes.Logout;
}
export type AuthActions = Logout;
// ../core/reducers/index.ts
// NGRX
import { ActionReducerMap, MetaReducer } from '@ngrx/store';
import { storeFreeze } from 'ngrx-store-freeze';
import { routerReducer } from '@ngrx/router-store';
import { environment } from '../../../environments/environment.prod';
// tslint:disable-next-line:no-empty-interface
export interface AppState { }
export const reducers: ActionReducerMap<AppState> = { router: routerReducer };
export const metaReducers: MetaReducer<AppState>[] = !environment.production ? [storeFreeze] : [];
解决方案
推荐阅读
- java - 当在java中提到集群名称时,弹性搜索是否会创建集群?
- jenkins-pipeline - Jenkins Pipeline emailext:如何在预发送脚本中访问构建对象
- javascript - 我们如何在电子邮件正文中添加徽标,并将徽标作为附件发送,使用 C# 或 PHP
- sql - 如何在 SQL Server 中拆分破折号分隔的值
- spring - 奇怪的行为 - websocket spring - 使用监听/通知 postgresql 向用户发送消息
- python - Python 请求 - 禁止错误(目录问题,即 ../ 减少)
- mysql - SQL - 插入多行而不加双
- javascript - 有条件地将元素推入数组
- settings - 以编程方式更改 IP 电话设置
- c++ - GraphicsMagick TTF 字体性能