【问题标题】:How can I pass an argument to a provider constructor in Ionic2 / Angular2?如何将参数传递给 Ionic2 / Angular2 中的提供者构造函数?
【发布时间】:2017-02-11 07:04:33
【问题描述】:

我正在尝试将我的 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
  ]
})

运行 ionic serve 时一切正常,但是当我尝试构建它时,出现以下错误:

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 中的构造函数或将其注入应用程序的方式?感谢您的帮助。

【问题讨论】:

  • 作为临时解决方案,我将参数设为可选,现在可以使用。但我仍在寻找合适的解决方案。

标签: angular typescript dependency-injection ionic2


【解决方案1】:

在您的应用模块中从@angular/http 导入HttpModule,如下所示:

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) {
  }
  ...
}

【讨论】:

  • 感谢您的快速回复,但是,我仍然遇到完全相同的问题。
  • 编辑也无效。编译新的AuthService时,构造函数还需要1个Argument(在编译好的js和d.ts文件中)。但是因为当我调整定义文件时它正在工作,我猜想在 JS 端一切正常。我注入的方式一定有问题。
【解决方案2】:

你必须改变定义提供者的方式:

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

最后一块是工厂函数:

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

另见Migrating to Ionic 2 RC 0 - ngc fails

【讨论】:

    【解决方案3】:

    我遇到了同样的问题,Markus 让我走上了正确的道路,但这是我需要做的事情(另请参阅 Angular docs Dependency Injection 下的“工厂供应商”):

    使注入服务中的构造函数参数可选。仅此还不够(http 在运行时未定义)

    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 ]
    })
    

    从 app.module.ts 中的 @NgModule 提供程序中删除服务。

    要在组件中使用服务,请从 Injector 获取它,而不是注入服务:

    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) {}
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多