Angular 2 - 无法实例化循环依赖

Posted

技术标签:

【中文标题】Angular 2 - 无法实例化循环依赖【英文标题】:Angular 2 - Cannot instantiate cyclic dependency 【发布时间】:2017-05-05 17:36:39 【问题描述】:

我创建了自定义 XHRBackend 类来全局捕获 401 错误。在 AuthService 中,我有 2 种使用 http 的方法 - login 和 refreshToken。所以我有这样的依赖链:Http -> customXHRBackend -> AuthService -> Http。我该如何解决这个问题?

export class CustomXHRBackend extends XHRBackend 
  constructor(browserXHR: BrowserXhr,
              baseResponseOptions: ResponseOptions,
              xsrfStrategy: XSRFStrategy,
              private router: Router,
              private authService: AuthService) 
    super(browserXHR, baseResponseOptions, xsrfStrategy);
  

  createConnection(request: Request): XHRConnection 
    let connection: XHRConnection = super.createConnection(request);
    connection.response = connection.response
      .catch(this.handleError.bind(this));

    return connection;
  

  handleError(error: Response | any) 
    console.log('ERROR',error['status']);
    if(error['status'] === 401) 
      this.authService.logout();
      this.router.navigate(['/']);
    

    return Observable.throw(error);
  

AuthService.ts

@Injectable()
export class AuthService 
  private loggedIn: boolean = false;

  constructor(private http: Http) 
    this.loggedIn = !!localStorage.getItem('authToken');
  

  login(email: string, password: string): Observable<Response> 
    let headers: Headers = new Headers();
    headers.set('Content-Type', 'application/json');

    return this.http.post('https://httpbin.org/post',
      
        email: email,
        password: password
      ,
      
        headers: headers
      )
      .map((response) => 
        let res = response.json();

        // if (res['success']) 
        if (res) 
          localStorage.setItem('authToken', res['token']);
          localStorage.setItem('refreshToken', res['refreshToken']);
          console.log('logged');
          this.loggedIn = true;
        

        return response;
      
    );
  

  logout(): void 
    localStorage.removeItem('authToken');
    this.loggedIn = false;

    console.log('Logged out');
  

  isLogged(): boolean 
    return this.loggedIn;
  

  refreshToken(): Observable<Response> 
    let headers: Headers = new Headers();
    headers.set('token', localStorage.getItem('token'));
    headers.set('refreshToken', localStorage.getItem('refreshToken'));

    return this.http.get('https://httpbin.org/get', 
      headers: headers
    );
  


在 app.module.ts 中包含 CustomXHRBackend


      provide: XHRBackend,
      useFactory: (browserXHR: BrowserXhr,
                   baseResponseOptions: ResponseOptions,
                   xsrfStrategy: XSRFStrategy,
                   router: Router,
                   authService: AuthService) => 
        return new CustomXHRBackend(browserXHR, baseResponseOptions, xsrfStrategy, router, authService);
      ,
      deps: [BrowserXhr, ResponseOptions, XSRFStrategy, Router, AuthService]
    

【问题讨论】:

查看***.com/questions/40525850/… 我看到了那个答案,但也许有比使用 setTimeout 更好的方法 ***.com/questions/40826073/… 我认为您不应该在您的CustomXHRBackend 中使用AuthService,因为XHRBackend 的级别低于您的AuthService。这看起来像是一种反模式,即使只处理一次错误很方便,但如果有解决方案,它可能有点“hacky”。​​ 那么第一条评论的答案呢? (或***.com/questions/40860202/…) 【参考方案1】:

请在构造函数中查看注入依赖项的位置。您不能在几个服务中注入相同的依赖项。示例:CustomXHRBackend => AuthService, AuthService => CustomXHRBackend

【讨论】:

【参考方案2】:

HTTP 拦截器怎么样...有一篇博文here。 如果你谷歌你会发现更多... Here's 如何将一个应用程序模块挂接到您的应用程序模块中 您可以在拦截器中克隆请求并将X-CustomAuthHeader 添加到标头等中。

【讨论】:

以上是关于Angular 2 - 无法实例化循环依赖的主要内容,如果未能解决你的问题,请参考以下文章

Angular 提供程序,循环依赖错误

spring-循环依赖

spring中的循环依赖

spring中的循环依赖

spring中的循环依赖

Spring:bean的循环依赖问题