在 Ionic 2 应用程序中使用自定义 Http 服务



我想对我的 Ionic 2 应用程序 (v2.0.0-beta.30) 中的每个 HTTP 请求做一些事情,所以我创建了自己的 Http 类来扩展 angular 的服务。像这样:

@Injectable()
export class myHttp extends Http
{
    private myStuff(): void
    {
        //stuff to fo every request
    }
    public request(url: string | Request, options?: RequestOptionsArgs): Observable<Response>
    {
        this.myStuff();
        return super.request(url, options);
    }
    public get(url: string, options?: RequestOptionsArgs): Observable<Response>
    {
        this.myStuff();
        return super.get(url, options);
    }
// etc.
}

我目前有东西在Http上调用函数,我不想改变所有东西来调用MyHttp。我希望任何提出请求的东西都不知道,也不在乎它实际上是在打电话MyHttp.似乎应该有一种方法可以提供MyHttp而不是Http,我只是不确定您会在哪里使用 Ionic 2 应用程序执行此操作。

我尝试将其添加为ionicBootstrap函数,如下所示:

ionicBootstrap(MyApp, [new ProviderBuilder(Http).toClass(MyHttp)], {});

这只会给我死机的白屏。我还尝试像这样添加到MyApp类的@Component装饰器中:

@Component({
    providers: [new ProviderBuilder(Http).toClass(MyHttp)],
    templateUrl: "build/app.html"
})

这给出了相同的白屏。我不确定我是否理解其中的区别,因为我尝试了toAlias而不是toClass相同的结果。

当任何东西想要注射时,我如何告诉注射器注射MyHttp Http

--------更新-----------

我终于通过尝试绕过了死机的白屏,还将HTTP_PROVIDERS包括在提供商阵列中。但是,它仍在注入Http,而不是MyHttp使用它的其他服务。我已经尝试了以下每种方法:

{ provide: Http, useClass: MyHttp }
provide(Http, {useClass: myHttp })
new ProviderBuilder(Http).toClass(MyHttp)

依赖于Http的服务如下所示:

public constructor(http: Http)
{
    //...
}

在这里放了一个调试器,我可以看到它是 angular 的Http而不是MyHttp

--------更新 2 -----------

尝试在不同的类上做同样的事情,我确实看到它有效。例如:

ionicBootstrap(MyApp, [new ProviderBuilder(MyOtherClass).toClass(MyOtherClass2)], {});

我看到MyOtherClass2在它要求MyOtherClass时被注射.所以,我不知道我是否MyHttp做错了什么,或者Http是否有一些错误。有没有人能够成功地用Http做到这一点?

就像

你在这里读到的那样,当你注册这样的provider时:

// bootstrap
ionicBootstrap(MyApp, [DataService]);
// component
@Component({
  ...
  providers: [DataService]
})
class AppComponent { }

您使用的是快捷方式,而不是编写以下内容:

// at bootstrap
ionicBootstrap(MyApp, [
  provide(DataService, {useClass: DataService})
]);
// or in component
@Component({
  ...
  providers: [
    provide(DataService, {useClass: DataService})
  ]
})
class AppComponent { }

您可以使用该快捷方式,因为它的值与令牌相同。所以在你的情况下,你必须这样做:

// at bootstrap
ionicBootstrap(MyApp, [
  provide(Http, { useClass: myHttp })
]);
// or in component
@Component({
  ...
  providers: [
    provide(Http, {useClass: myHttp })
  ]
})
class AppComponent { }

请记住,如果将其添加到Component每次加载该组件时都会创建该服务的新实例。如果要在整个应用程序(单一实例)中使用相同的实例,则必须将其添加到应用的ionicBootstrap最顶层Component中。

这对我有用:

你的 myHttp 应该以构造函数开头:

@Injectable()
export class myHttp extends Http{
...
    constructor(
        xhrBackend: XHRBackend,
        requestOptions: RequestOptions) {
        super(xhrBackend, requestOptions);
    }

在您的 app.module.ts 中,您应该将提供程序导入为:

import { Http, XHRBackend, RequestOptions } from '@angular/http';
...
@NgModule({
  ...
  providers: [
    {
      provide: Http,
      useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => {
        return new myHttp(backend, defaultOptions);
      },
      deps: [XHRBackend, RequestOptions]
    }
  ]

你不能使用[new...],你能试试{ provide: Http, useClass: MyHttp }这将是ionicBootstrap(MyApp, [{ provide: Http, useClass: MyHttp }], {});

最新更新