如何在 intercept/arrow 函数中引用组件对象?
How to refer to component object within intercept/arrow function?
这是我的代码:
export class NetworkInterceptor implements HttpInterceptor {
constructor(private router: Router, private ngZone: NgZone) {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
// ...
return next.handle(request).pipe(
finalize(() => {
// ...
}),
tap({
next(res) {},
error(error) {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
this.ngZone.run(() => this.router.navigateByUrl('/account/signin'));
}
}
},
complete() {},
})
);
}
}
但是不能用
this.ngZone.run(() => this.router.navigateByUrl('/account/signin'))
在 intercept
中,因为 this
不引用组件的对象。
正确的做法是什么?
尝试在拦截函数内为路由器实例声明一个局部变量。然后在代码中使用该变量。
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
// ...
const interceptorRouter = this.router;
return next.handle(request).pipe(
finalize(() => {
// ...
}),
tap({
next(res) { },
error(error) {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
this.ngZone.run(() => interceptorRouter.navigateByUrl('/account/signin'));
}
}
},
complete() { }
})
);
}
这是我在过去的应用程序中使用的一种非常简单的方法,我不知道你是否觉得它足够优雅:
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private router: Router, @Inject(WINDOW) private window: Window) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError((error: HttpErrorResponse) => {
if (error?.status === 401) {
logout(this.window, this.router);
}
return throwError(error);
})
);
}
}
如果与Window
& Router
相同,您可以注入NgZone
。
如果打算使用路由器服务导航到路由,则出现 401 错误时,您不需要使用 ngZone。 ngZone 是我们在从 angular 的 scope/zone.
外部引入 angular 事件时使用的服务
您需要以更简单的方式使用 catchError,您将通过以下方式为胜利做好准备:
export class NetworkInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
// ...
return next.handle(req).pipe(
catchError((err) => {
if (err instanceof HttpErrorResponse && err.status === 401) {
this.router.navigateByUrl('/account/signin');
}
return throwError(err);
})
);
}
}
只需为您的点击负载使用箭头函数
tap({
next: () => {...},
error: () => {...},
complete: () => {...},
})
EDIT 个人意见,但您应该使用 catchError
运算符,这似乎更适合您的情况。
这是我的代码:
export class NetworkInterceptor implements HttpInterceptor {
constructor(private router: Router, private ngZone: NgZone) {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
// ...
return next.handle(request).pipe(
finalize(() => {
// ...
}),
tap({
next(res) {},
error(error) {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
this.ngZone.run(() => this.router.navigateByUrl('/account/signin'));
}
}
},
complete() {},
})
);
}
}
但是不能用
this.ngZone.run(() => this.router.navigateByUrl('/account/signin'))
在 intercept
中,因为 this
不引用组件的对象。
正确的做法是什么?
尝试在拦截函数内为路由器实例声明一个局部变量。然后在代码中使用该变量。
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
// ...
const interceptorRouter = this.router;
return next.handle(request).pipe(
finalize(() => {
// ...
}),
tap({
next(res) { },
error(error) {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
this.ngZone.run(() => interceptorRouter.navigateByUrl('/account/signin'));
}
}
},
complete() { }
})
);
}
这是我在过去的应用程序中使用的一种非常简单的方法,我不知道你是否觉得它足够优雅:
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private router: Router, @Inject(WINDOW) private window: Window) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError((error: HttpErrorResponse) => {
if (error?.status === 401) {
logout(this.window, this.router);
}
return throwError(error);
})
);
}
}
如果与Window
& Router
相同,您可以注入NgZone
。
如果打算使用路由器服务导航到路由,则出现 401 错误时,您不需要使用 ngZone。 ngZone 是我们在从 angular 的 scope/zone.
外部引入 angular 事件时使用的服务您需要以更简单的方式使用 catchError,您将通过以下方式为胜利做好准备:
export class NetworkInterceptor implements HttpInterceptor {
constructor(private router: Router) {}
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
// ...
return next.handle(req).pipe(
catchError((err) => {
if (err instanceof HttpErrorResponse && err.status === 401) {
this.router.navigateByUrl('/account/signin');
}
return throwError(err);
})
);
}
}
只需为您的点击负载使用箭头函数
tap({
next: () => {...},
error: () => {...},
complete: () => {...},
})
EDIT 个人意见,但您应该使用 catchError
运算符,这似乎更适合您的情况。