@Inject与构造函数注入作为Angular 2中的普通参数有什么区别?

时间:2016-10-13 09:49:31

标签: angular

在这两种情况下我有点困惑,我们使用@Injectable()装饰器标记一些类,以便它们可用于注入不同的组件。我只想知道正常情况下 @Inject()构造函数注入之间有什么区别。

场景1 - 使用@Inject():

@Component({
    selector: 'main-app',
    template: `
        ....
        {{_service.getName()}}
        ....
    `
})
export class AppComponent{
    constructor(@Inject(AppService) private _service){}
    ....
}

场景2 - 使用正常参数:

@Component({
    selector: 'main-app',
    template: `
        ....
        {{_service.getName()}}
    `
})
export class AppComponent{
    constructor(private _service:AppService){}
    ....
}

两种情况都有效,有什么区别吗?谁应该更优选?

1 个答案:

答案 0 :(得分:16)

对于注入标记不是类的情况,您真的应该只使用@Inject。如果您不熟悉令牌是什么,它基本上是Angular用来识别要注入的内容。例如

providers: [
  AuthService,
  { provide: Http, useValue: new CustomHttpImpl() }
]

此处我们有两个不同的提供商,AuthServiceCustomHttpImpl。使用AuthService令牌为AuthService。这意味着我们使用AuthService类型

来注入AuthService
constructor(private authService: AuthService) {}

使用此构造函数,Angular知道要使用令牌AuthService查找AuthService

在第二个提供商中,我们提供了CustomHttpImpl,但这次我们使用了令牌Http。所以我们不能注入CustomHttpImpl我们需要注入Http,因为那是令牌

// this will actually be the CustomHttpImpl, not Angular's Http
constructor(private http: Http)

// error: No provider for CustomHttpImpl
constructor(private http: CustomHttpImpl)

所以你可以从中看出,令牌都是类,这足以让Angular知道如何注入。

但是,让我们说我们有一个String或一个我们想要注入的数组。我们无法将其与任何类令牌联系起来,因此我们需要创建一个人工令牌

import { OpaqueToken } from '@angular/core';

let numbers = [ 1, 2, 3, 4 ];
let config = '{ "some": "json", "config": "data" }'

const NUMBERS = new OpaqueToken('app.numbers');
const CONFIG = new OpaqueToken('app.config');

现在我们有我们想要注入的物品的令牌。当我们配置providers时,我们使用这些令牌,当我们注入时,我们@Inject(TOKEN)

providers: [
  { provide: NUMBERS, useValue: numbers },
  { provide: CONFIG, useValue: config }
]

constructor(@Inject(NUMBERS) numbers: number[], @Inject(CONFIG) config: string)

更新

现在,使用Angular 4,我们应该使用InjectionToken而不是OpaqueToken