【问题标题】:Custom service in extended Http not getting injected扩展 Http 中的自定义服务未注入
【发布时间】:2016-12-19 15:11:05
【问题描述】:

我想扩展 Http 提供程序以拦截所有提供 403 状态的请求以处理自动注销。 我的自定义 InterceptingHttp 应该声明为 Http 提供程序,所以我不需要关心“特殊”http 提供程序。

我必须关注:

我的自定义 Http 提供程序

import { Injectable } from '@angular/core';
import { Request, XHRBackend, RequestOptions, Response, Http, RequestOptionsArgs } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { AuthenticationService } from './../services/authentication.service';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class InterceptingHttpService extends Http {

    constructor(backend: XHRBackend, defaultOptions: RequestOptions, private authenticationService: AuthenticationService) {
    super(backend, defaultOptions);
    }

    request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    var self = this;
    return super.request(url, options).catch((res: Response) => {
        if (res.status === 403) {
        console.log('intercepted');
        self.authenticationService.logout();
        }
        return Observable.throw(res);
    });
    }
}

在 NgModule 中作为常规 Http 提供者的声明

    @NgModule({
    imports: [
        BrowserModule,
        ToastyModule.forRoot(),
        HttpModule,
    FormsModule,
        routing,
        Ng2BootstrapModule,
    PaginationModule
    ],

    declarations: [
        AppComponent,
        NavHeaderComponent,
        FooterCopyrightComponent,
        InventoryRootComponent,
        InventoryTreeComponent,
        InventoryDetailComponent,
        SetModelComponent,
        MetadataListComponent,
        MetadataDetailComponent,
        ScriptGeneratorComponent,
        SetDetailComponent,
        SetVersionComponent,
        SetContainerTreeComponent,
        SetContainerDetailComponent,
        FilterByPropertyPipe,
        OrderContainersByLeafPipe,
        ResolveStateId,
        ConfirmComponent,
        FocusDirective
    ],
    providers: [
    SetService,
        SetTypeService,
        SetContainerService,
        StateService,
        NotificationService,
        MetadataService,
        MetadataTypeService,
        EntityService,
        SetContainerMetadataService,
    AuthenticationService,
    InterceptingHttpService,
        ConfirmService,
        SiteVersionService,
    {
        provide: Http,
        useFactory: (backend: XHRBackend, defaultOptions: RequestOptions, authenticationService: AuthenticationService) => {
        return new InterceptingHttpService(backend, defaultOptions, authenticationService);
        },
        deps: [XHRBackend, RequestOptions, AuthenticationService]
    },
    ],
    bootstrap: [AppComponent]
})

它被加载并拦截所有 403 响应。唯一奇怪的是,authenticationService 是未定义的。

我想我的供应商声明可能有误。我尝试将AuthenticationService 添加到deps 数组中,这只会导致循环依赖错误。

我的错误在哪里?如何在我的扩展 Http 提供程序中使用我的AuthenticationService

【问题讨论】:

  • 如果你使用() =&gt;,则不需要self
  • 你在constructor(...) { super(...); console.log(authenticationService); }这样的构造函数中检查过是否传入了值吗?
  • @GünterZöchbauer 没错。这是一个遗留物。谢谢
  • 果然是undefined
  • 您使用的是哪个 Angular2 版本?不久前 DI 和扩展类存在问题。

标签: angular dependency-injection angular2-http


【解决方案1】:

你需要将AuthenticationService添加到deps

deps: [XHRBackend, RequestOptions, AuthenticationService]

Http 被注入到AuthenticationService 时,这将导致 DI 无法解析的循环依赖。

请参阅DI with cyclic dependency with custom HTTP and ConfigService 了解如何解决循环依赖的方法。

【讨论】:

  • 我一直在尝试这个,但在新版本的 Angular 中,它最终以Cannot instantiate cyclic dependency! Http: in NgModule AppModule in ./AppModule
  • 如果刚刚用完整的 ngModule 声明更新了我的问题
  • AuthenticationService 可能确实注入了Http。见stackoverflow.com/questions/40860202/…
  • 我使用您发布的附加链接中的解决方案进行了尝试,现在它可以按预期工作。也许您也可以将链接添加到您的答案中,并附上关于循环依赖的评论。
  • 感谢您的提示 - 完成。很高兴听到你能让它工作:)
猜你喜欢
  • 1970-01-01
  • 2017-01-06
  • 1970-01-01
  • 2016-03-30
  • 1970-01-01
  • 1970-01-01
  • 2017-08-08
  • 2016-09-02
  • 1970-01-01
相关资源
最近更新 更多