Angular CLI: 11.0.1
Node: 14.8.0
OS: darwin x64
Angular: 11.0.0
... animations, cdk, common, compiler, compiler-cli, core, forms
... language-service, material, platform-browser
... platform-browser-dynamic, router
Ivy Workspace: Yes
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1002.0
@angular-devkit/build-angular 0.1100.1
@angular-devkit/core 10.2.0
@angular-devkit/schematics 11.0.1
@angular/cli 11.0.1
@schematics/angular 11.0.1
@schematics/update 0.1100.1
rxjs 6.6.3
typescript 4.0.5
当我将translateService与httpInterceptor一起使用时,出现以下错误:
NG0200:在DI中检测到InjectionToken HTTP_INTERCEPTORS的循环依赖关系
如果我不使用translateService,它工作得很好,有人能帮我解决这个问题吗?下面是代码
app.component.ts
import { Component } from '@angular/core';
import { ElectronService } from './services';
import { TranslateService } from '@ngx-translate/core';
import { AppConfig } from '../environments/environment';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
constructor(
private electronService: ElectronService,
private translate: TranslateService
) {
this.translate.setDefaultLang('en');
console.log('AppConfig', AppConfig);
}
}
core.module.ts
import {InjectionToken, NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {BrowserModule} from '@angular/platform-browser';
import {FormsModule} from '@angular/forms';
import {HttpClient, HttpClientModule} from '@angular/common/http';
import {SharedModule} from '../shared/shared.module';
import {AppRoutingModule} from '../app-routing.module';
import {TranslateLoader, TranslateModule} from '@ngx-translate/core';
import {TranslateHttpLoader} from '@ngx-translate/http-loader';
import {AppStoreModule} from '../store/app-store.module';
import {ViewsModule} from '../views/views.module';
import {httpInterceptorProvides} from '../services/http-interceptor';
import {API_BASE_URL} from '../services/service.module';
// AoT requires an exported function for factories
export function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
return new TranslateHttpLoader(http, '../../assets/i18n/', '.json');
}
@NgModule({
declarations: [],
imports: [
CommonModule,
BrowserModule,
FormsModule,
HttpClientModule,
AppStoreModule,
SharedModule,
ViewsModule,
AppRoutingModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: HttpLoaderFactory,
deps: [HttpClient]
}
})
],
providers: [
{
provide: API_BASE_URL,
useValue: 'https://demo.xx.com'
},
httpInterceptorProvides,
],
exports: [AppRoutingModule, SharedModule]
})
export class CoreModule {
}
httpinterceptor.ts
import {Inject, Injectable} from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import {Observable} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {AuthService} from '../auth.service';
import {API_BASE_URL} from '../service.module';
@Injectable()
export class CommonInterceptor implements HttpInterceptor {
skipUrl: string[];
constructor(private auth: AuthService, @Inject(API_BASE_URL) private uri: string) {
this.skipUrl = ['/oauth/token', 'assets/i18n'];
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const req = request.clone({
setHeaders: {
'Accept': 'dddd'
},
url: this.uri + request.url
});
// return next.handle(req);
if (this.isSkipAuth(req.url)) {
return next.handle(req);
} else {
return this.auth.getToken()
.pipe(
switchMap((access_token) => {
const reqA = req.clone({
setHeaders: {
'Authorization': 'Bearer ' + access_token
}
});
return next.handle(reqA);
})
);
}
}
isSkipAuth(url: string): boolean {
let isMatch = false;
this.skipUrl.forEach((reg_url: string) => {
if (!isMatch) {
if (url.search(reg_url) >= 0) {
isMatch = true;
}
}
});
return isMatch;
}
}
auth.service.ts
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable, of} from 'rxjs';
import {ElectronService} from './electron/electron.service';
import {map, pluck, tap} from 'rxjs/operators';
import {ResponseType} from './data-types/common.type';
export interface TokenModel {
access_token: string; // access_token
expires: number; //
expires_in: number; //
}
@Injectable({
providedIn: 'root'
})
export class AuthService {
elStoreIns: any;
constructor(private http: HttpClient, private elService: ElectronService) {
this.elStoreIns = this.elService.elStore;
}
getToken(): Observable<string> {
const now = Date.now();
const tokenStore: TokenModel = this.elStoreIns.get('token');
if (tokenStore instanceof Object) {
if ((now - tokenStore.expires) <= 7100 * 1000) {
return of(tokenStore.access_token);
}
}
return this.requestToken();
}
requestToken(): Observable<string> {
return this.http.post<ResponseType>('/oauth/token', {
client_ids: 1,
client_secrets: 'ddd',
grant_types: 'dddd'
}).pipe(
pluck('data'),
tap((data: any) => {
const tokenData: TokenModel = {
access_token: data.access_token,
expires_in: data.expires_in,
expires: Date.now()
};
this.saveToken(tokenData);
}),
map(data => data.access_token)
);
}
saveToken(tokenStore: TokenModel): void {
this.elStoreIns.set('token', tokenStore);
}
}
1条答案
按热度按时间hgqdbh6s1#
我不能100%确定它是否是一个有效的干净的解决方案,但是您可以尝试在“auth.service.ts”中自己示例化“HttpClient”。从您的构造函数中删除HttpClient,并尝试以下方法: