angular - 如何将动态变量从服务传递给 http_interceptor
问题描述
我有多个角度项目,每个项目都有一个调用相同 API 的服务。我一直在向请求添加一个标头,以确定从哪个应用程序发送了请求。所以我一直在尝试创建一个具有基本服务类的库来设置标头值
@Injectable({ providedIn: "root" })
export class AppbaseService {
scope: string;
constructor(@Inject(forwardRef(()=>'scope')) scope:string) {
this.scope = scope;
}
getScope():string{
return this.scope;
}
}
和一个http 拦截器,用于将该动态值作为标头附加到请求中
@Injectable()
export class ScopeInterceptor implements HttpInterceptor {
constructor(private appBaseService: AppbaseService) {
}
intercept(req: HttpRequest<any>,
next: HttpHandler): Observable<HttpEvent<any>> {
const clonedRequest = req.clone({
headers: req.headers.append(
'Scope',
this.appBaseService.scope
)
});
return next.handle(clonedRequest);
}
}
最后是一个将动态值设置为提供者的工厂
export function appValueFactory(baseService: AppbaseService) {
console.log(baseService);
return baseService.getScope();
}
但我不知道如何在模块中设置提供程序并低于错误,这不是很有帮助。
Uncaught Error: Can't resolve all parameters for qI: (?).
at Jt (main.js:1)
at e._getDependenciesMetadata (main.js:1)
at e._getFactoryMetadata (main.js:1)
at e.getProviderMetadata (main.js:1)
at main.js:1
at Array.forEach (<anonymous>)
at e._getProvidersMetadata (main.js:1)
at main.js:1
at Array.forEach (<anonymous>)
at e._getProvidersMetadata (main.js:1)
有人可以指出我正确的方向吗?
谢谢你。
解决方案
首先,¿这是为了什么:@Inject(forwardRef(()=>'scope'))
?在构造函数中,您应该注入服务并且范围是一个字符串。
我知道scope
是当前应用程序的字符串标识符,因此简单的解决方案是直接在拦截器中添加该字符串。
如果您希望使用服务来获取该字符串,问题将在里面AppbaseService
,因为值是异步的(它填充在构造函数中)所以,如果您的代码在创建之前scope
尝试调用,将是未定义的。ScopeInterceptor
AppbaseService
scope
为了解决这个问题,让服务返回一个 Observable(我们假设scopeService.getAppScope()
返回这个应用的范围字符串)
export class AppbaseService {
scope = new BehaviorSubject<string>('');
constructor(private scopeService: ScopeService) {
this.scope.next(scopeService.getAppScope());
}
getScope$(): Observable<string> {
return this.scope.asObservable();
}
}
并且从拦截器使用这个异步函数并返回一个 Observable:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.appBaseService.getScope$().pipe(
filter(scope => !!scope),
take(1),
switchMap(scope => {
const clonedRequest = req.clone({
headers: req.headers.append('Scope',scope)
});
return next.handle(clonedRequest);
}))
}
rxjs函数说明:
- 用于过滤未定义的
filter
值:当范围尚未定义时,不要继续使用管道。 take(1)
:一旦收到值,只消费一次可观察对象然后完成。switchMap
: 从范围 observable 中获取值并返回另一个 observableHttpEvent
推荐阅读
- java - 如何使 customActionBar 透明并更改其文本颜色?
- ms-word - 使用通配符在 Word 中查找和替换
- laravel - Vue没有根据方法更新计算属性,但是直接调用时相同的方法返回正确的值
- reactjs - 反应:道具未在地图功能内更新
- c++ - 当不应存在子字符串时,具有多个字符的 find_first_of 不返回 string::npos
- python - 条目如何连接到方法
- javascript - 如何在数据表中添加新行并重新排序每行的索引?
- excel - 按顺序对 Excel 中的数据进行排序
- ios - 特定时间段的本地通知取消
- javascript - 如何使用 pug 迭代 json 数组?