【问题标题】:Ionic2 DI: Provide interface implementation to componentIonic2 DI:为组件提供接口实现
【发布时间】:2016-08-01 23:38:24
【问题描述】:

我想将接口的实现注入 Ionic2 组件(Ionic2 Beta 10,使用 Angular2 RC4)。假设我们有以下服务:

export interface ServiceInterface { /*...*/ }
@Injectable()
export class ServiceImpl implements ServiceInterface { /*...*/ }

如何将其注入 Ionic2 组件?我试过了:

import { Component, provide, Provider } from '@angular/core';
import { ServiceInterface } from './service.interface';
import { ServiceImpl } from './service.impl';

@Component({
    providers: [
        // Exception: Can't resolve all parameters for SomeComponent: (?)
        ServiceImpl,

        // @deprecated - seen on: http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html
        provide(ServiceInterface, {useClass: ServiceImpl}),

        // @deprecated - seen on: http://plnkr.co/edit/RSTG86qgmoxCyj9SWPwY?p=preview
        new Binding(ServiceInterface, {toAlias: ServiceImpl}),

        // @deprecated - seen on: https://www.dartdocs.org/documentation/angular2/2.0.0-beta.9/angular2/Provider/useClass.html
        new Provider(ServiceInterface, {useClass: ServiceImpl}),

        // TS Error: Cannot find name 'ServiceInterface' - even though it is properly referenced
        {provide: ServiceInterface, useClass: ServiceImpl}
    ]
})
export class SomeComponent {
    constructor(private service: ServiceInterface) {}
}

按以下方式简单地使用ServiceImpl 就可以了,但这不是我想要的:

@Component({providers: [ServiceImpl]})
export class SomeComponent {
    constructor(private service: ServiceImpl) {}
}

任何想法我缺少什么?

【问题讨论】:

标签: typescript angular ionic2


【解决方案1】:

在 TypeScript 中,接口不会在运行时保留(它们只是消失了),因此会出现 Cannot find name 'ServiceInterface' 错误。

当你使用时

{provide: ServiceInterface, useClass: ServiceImpl}

provide 部分是一个令牌。您现在使用的是不存在的令牌(界面)。一种可能的解决方法是使用字符串作为标记。

另一种可能的方法是使用OpaqueToken 而不是字符串。您可以声明一个与接口同名的接口。可以这样做:

import { Component, Injectable, provide, Provider, OpaqueToken, Inject } from '@angular/core';

export interface ServiceInterface { /*...*/ }
@Injectable()
export class ServiceImpl implements ServiceInterface { /*...*/ }

const ServiceInterface = new OpaqueToken("ServiceInterface");  // <----- token defined

@Component({
  selector: 'my-app',
  template: '<h1>My First Angular 2 App</h1>',
  providers: [{provide: ServiceInterface, useClass: ServiceImpl}] // <-- providing
})
export class AppComponent {
    constructor(@Inject(ServiceInterface) private service: ServiceInterface) {}
                        ^^^^^^^^^^^^^^^^-- injecting
}

demo plunker

【讨论】:

  • PS.:OpaqueToken 技术主要用于角度源本身:github.com/angular/angular/…
  • 这出乎意料,开发者体验肯定有提升空间! OpaqueToken 仍然给混乱和粗心的错误留下了很大的空间。
猜你喜欢
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 1970-01-01
  • 2019-03-04
  • 2013-04-03
  • 1970-01-01
相关资源
最近更新 更多