Как передать аргумент конструктору поставщика в Ionic2/Angular2?

Я пытаюсь перенести приложение Ionic2.beta11 в новую версию Ionic2.rc0. Большинство вещей были довольно прямолинейными, но у меня проблема с компилятором AoT.

У меня есть AuthService:

@Injectable()
export class AuthService {
  constructor(@Inject(Http) http: Http) {
    this.http = http;
  }
  ...
}

Я ввожу его в свое приложение в файле src/app/app.module.ts:

@NgModule({
  declarations: [
    MyApp,
    ...
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    ...
  ],
  providers: [
    AuthService
  ]
})

Все работает отлично, когда работает ионная подача, но когда я пытаюсь ее построить, я получаю следующую ошибку:

ngc error: Error: Error at .../.tmp/app/app.module.ngfactory.ts:397:78: Supplied parameters do not match any signature of call target.

Линии 396 - 399:

get _AuthService_74():import44.AuthService {
  if ((this.__AuthService_74 == (null as any))) { (this.__AuthService_74 = new import44.AuthService()); }
  return this.__AuthService_74;
}

Проблема заключается в том, что new import44.AuthService() ожидает аргумент типа http.

Интересно, что все отлично работает, когда я вручную заменяю constructor(http: Http) на constructor() в файле определения.

Я прочитал все ответы StackOverflow, которые мог найти, но ни одно из решений не решило мою проблему.

Нужно ли мне менять конструктор в AuthService или как я ввожу его в свое приложение? Благодарим вас за помощь.

Ответ 1

Вы должны изменить способ определения поставщика:

@NgModule({
  ...
  providers: [
    Http,
    {
      provide: AuthService,
      useFactory: getAuthService,
      deps: [Http]
    }
  ]
})

Последняя часть - это функция factory:

export function getAuthService(http: Http): LoggingService {
  return new AuthService(http);
}

См. также Миграция в Ionic 2 RC 0 - ngc не работает

Ответ 2

У меня была та же проблема, и Маркус поставил меня на правильный путь, но вот что мне нужно было сделать, чтобы перейти (см. также "Factory Провайдеры" в Angular docs Инъекция зависимостей):

Сделать параметр конструктора в инжектированной службе необязательным. Одного этого недостаточно (http был undefined во время выполнения)

constructor(public http?: Http){}

Создайте класс поставщика услуг SomeServiceProvider.ts:

import { Http } from '@angular/http';
import { SomeService } from 'some-service';

export function someServiceFactory(http: Http){
  return new SomeService(http);
}

export let SomeServiceProvider =
  { provide: SomeService,
    useFactory: someServiceFactory,
    deps: [ Http ]
  };

В корневом app.component.ts добавьте поставщика услуг:

@Component({
  ...
  providers: [ SomeServiceProvider ]
})

Удалите службу из поставщиков @NgModule в app.module.ts.

Чтобы использовать сервис в компонентах, используйте его Инжектор вместо того, чтобы вводить службу:

import { Component, Injector } from '@angular/core';
import { SomeService } from 'some-service';

@Component({
  ...
})

export class MyComponent{
  someService: SomeService = this.injector.get(SomeService);

  constructor(private injector: Injector) {}

}

Ответ 3

Импортируйте HttpModule из @angular/http в свой модуль приложения, как показано ниже:

import { HttpModule } from '@angular/http';
@NgModule({
  declarations: [
    MyApp,
    ...
  ],
  imports: [
    HttpModule,
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    ...
  ],
  providers: [
    AuthService
  ]
})

Измените свой сервис, как показано ниже, и отметьте один раз:

import { Http } from '@angular/http';
@Injectable()
export class AuthService {
  constructor(private http: Http) {
  }
  ...
}