代码之家  ›  专栏  ›  技术社区  ›  santosh kumar patro

无法实例化循环依赖项!HTTP_拦截器(“[错误->]”):在NgModule CoreModule中

  •  0
  • santosh kumar patro  · 技术社区  · 7 年前

    我使用以下依赖项:

    package.json包:

    {
      "name": "myApp",
      "version": "0.0.0",
      "license": "MIT",
      "scripts": {
        "ng": "ng",
        "start": "ng serve --base-href /myapp/",
        "build": "ng build",
        "build-stage": "ng build --environment=stage --aot --prod --vendor-chunk=false --common-chunk=false",
        "build-prod": "ng build --environment=prod --aot --prod --vendor-chunk=false --common-chunk=false",
        "test": "ng test",
        "lint": "ng lint",
        "e2e": "ng e2e"
      },
      "private": true,
      "dependencies": {
        "@angular/animations": "^4.2.4",
        "@angular/common": "^4.2.4",
        "@angular/compiler": "^4.2.4",
        "@angular/core": "^4.2.4",
        "@angular/forms": "^4.2.4",
        "@angular/http": "^4.2.4",
        "@angular/platform-browser": "^4.2.4",
        "@angular/platform-browser-dynamic": "^4.2.4",
        "@angular/router": "^4.2.4",
        "@ngx-translate/core": "^7.2.2",
        "@ngx-translate/http-loader": "^1.1.0",
        "bootstrap": "^3.3.7",
        "core-js": "^2.4.1",
        "jquery": "^3.2.1",
        "qrcode": "^1.0.0",
        "rxjs": "^5.4.2",
        "zone.js": "^0.8.14"
      },
      "devDependencies": {
        "@angular/cli": "1.4.2",
        "@angular/compiler-cli": "^4.2.4",
        "@angular/language-service": "^4.2.4",
        "@types/jasmine": "~2.5.53",
        "@types/jasminewd2": "~2.0.2",
        "@types/node": "~6.0.60",
        "codelyzer": "~3.1.1",
        "jasmine-core": "~2.6.2",
        "jasmine-spec-reporter": "~4.1.0",
        "karma": "~1.7.0",
        "karma-chrome-launcher": "~2.1.1",
        "karma-cli": "~1.0.1",
        "karma-coverage-istanbul-reporter": "^1.2.1",
        "karma-jasmine": "~1.1.0",
        "karma-jasmine-html-reporter": "^0.2.2",
        "protractor": "~5.1.2",
        "ts-node": "~3.2.0",
        "tslint": "~5.3.2",
        "typescript": "~2.3.3"
      }
    }
    

    跨域.service.ts:

    import { Injectable, NgZone } from '@angular/core';
    import { Subject } from 'rxjs/Subject';
    import { BehaviorSubject } from 'rxjs/BehaviorSubject';
    
    import { environment } from '../../environments/environment';
    import { ArticlePreview } from './article.model';
    
    import { TranslateService } from '@ngx-translate/core';
    
    @Injectable()
    export class CrossDomainService {
      globalSelectors = new Subject<GlobalSelectors>();
      globalLanguage = new BehaviorSubject<string>('en');
      initialArticlePath: string;
      initialGlobalSelectors: GlobalSelectors;
      private socket;
    
      constructor(private zone: NgZone,private translateService: TranslateService) {
        translateService.setDefaultLang('en');
      }
    
      public init() {
        if (this.inIframe) {
          const self = this;
          this.socket = new window['easyXDM'].Socket({
            onMessage(_response) {
              try {
                const response = JSON.parse(_response);
                self.zone.run(() => {
                  switch (response.type) {
                    case 'tileActionQuery': {
                      if (response.data.action && response.data.action === 'goToArticle') {
                        self.initialArticlePath = response.data.path;
                      }
                      break;
                    }
                    case 'setGlobalSelectors': {
                      self.initialGlobalSelectors = response.data;
                      self.globalSelectors.next(response.data);
                      break;
                    }
                    case 'tileInfo': {
                      self.globalLanguage.next(response.data.tileLanguage); 
                      self.translateService.use(response.data.tileLanguage);                
                      break;
                    }
                  }
                });
              } catch (e) {}
            },
            remote: environment.dashboardSiteUrl
          });
        }
      }          
    
      private get inIframe () {
        try {
          return window.self !== window.top;
        } catch (e) {
          return true;
        }
      }
    }
    
    export interface GlobalSelectors {
      client?: any[];
      jurisdiction?: any[];
      process?: any[];
      year?: any[];
    }
    

    应用模块:

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule, APP_INITIALIZER } from '@angular/core';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    
    import { AnalyticsService, CoreModule, CrossDomainService } from './core';
    import { TileModule } from './tile/tile.module';
    
    
    @NgModule({
      declarations: [AppComponent],
      imports: [
        BrowserModule,
        AppRoutingModule,
        TileModule,
        CoreModule
      ],
      providers: [
        {
          provide: APP_INITIALIZER,
          useFactory: onModuleInit,
          multi: true,
          deps: [CrossDomainService, AnalyticsService]
        }
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule {}
    
    export function onModuleInit(crossDomainService: CrossDomainService, analyticsService: AnalyticsService) {
      return () => {
        crossDomainService.init();
        analyticsService.init();
        return new Promise((resolve) => resolve(true));
      };
    }
    

    核心模块:

    import { NgModule } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { HTTP_INTERCEPTORS, HttpClientModule ,HttpClient } from '@angular/common/http';
    
    import { HttpRequestInterceptor } from './http-request.interceptor';
    import { ArticleService } from './article.service';
    import { CrossDomainService } from './cross-domain.service';
    import { AnalyticsService } from './analytics.service';
    
    import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
    import { TranslateHttpLoader } from '@ngx-translate/http-loader';
    
    export function translateHttpLoaderFactory(http: HttpClient) {
      return new TranslateHttpLoader(http);
    }
    
    @NgModule({
      imports: [
        CommonModule,
        HttpClientModule,
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useFactory: translateHttpLoaderFactory,
            deps: [HttpClient]
          }
        })
      ],
      providers: [
        ArticleService,
        CrossDomainService,
        AnalyticsService,
        {
          provide: HTTP_INTERCEPTORS,
          useClass: HttpRequestInterceptor,
          multi: true
        }
      ]
    })
    export class CoreModule {}
    

    http-request.interceptor.ts:

    import { Injectable } from '@angular/core';
    import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
    import { Observable } from 'rxjs/Observable';
    import { CrossDomainService } from './cross-domain.service';
    
    
    @Injectable()
    export class HttpRequestInterceptor implements HttpInterceptor {
    
      language: string = 'en';
    
      constructor(private crossDomainService: CrossDomainService) {
        crossDomainService.globalLanguage.subscribe((language) => {
          this.language = language;
        });
      }
    
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        const request = req.headers.has('Accept-Language') ?
          req :      
          req.clone({ setHeaders: { 'Accept-Language': this.language } });
    
        return next.handle(request);
      }
    }
    

    在编译项目时,我遇到一个错误:

    ERROR in Error: Provider parse errors:
    Cannot instantiate cyclic dependency! HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule CoreModule in C:/temp/myApp/src/app/core/core.module.ts@-1:-1
        at NgModuleProviderAnalyzer.parse (C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:11699:19)    at NgModuleCompiler.compile (C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:18548:36)
        at AotCompiler._compileModule (C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:24004:32)
        at C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:23916:66    at Array.forEach (<anonymous>)
        at AotCompiler._compileImplFile (C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:23916:19)
        at C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:23829:87
        at Array.map (<anonymous>)
        at AotCompiler.emitAllImpls (C:\temp\myApp\node_modules\@angular\compiler\bundles\compiler.umd.js:23829:52)
        at CodeGenerator.emit (C:\temp\myApp\node_modules\@angular\compiler-cli\src\codegen.js:42:46)
        at C:\temp\myApp\node_modules\@angular\compiler-cli\src\codegen.js:33:61
        at <anonymous>
        at process._tickCallback (internal/process/next_tick.js:188:7)
    

    有人能帮我解决这个问题吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Chellappan வ    7 年前

    尝试不在构造函数中设置CrossDomainService,而是在intercept函数中获取

    @Injectable()
    export class HttpRequestInterceptor implements HttpInterceptor {
    
    
      constructor(private injector: Injector) {
    
      }    
      intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
       // try to call the service here.
        language: string = 'en';
        const lanaguageInj= this.injector.get(CrossDomainService);
        const globalLanguage= auth.globalLanguage.subscribe((language) => {
          this.language = language;
        });
    
        const request = req.headers.has('Accept-Language') ?
          req :      
          req.clone({ setHeaders: { 'Accept-Language': this.language } });
    
        return next.handle(request);
      }
    }
    
    推荐文章