@Inject@Injectable

看起来像@SomeName的语句是装饰器。 装饰器 是JavaScript的扩展。 简而言之,装饰器让程序员修改和/或标记方法,类,属性和参数。有很多种装饰器。 在本节中,重点将放在与DI相关的装饰器:@Inject@Injectable。 有关装饰器的更多信息,请参阅EcmaScript 6和TypeScript特性部分

@Inject()

@Inject()是一个手动机制,让Angular 2知道必须注入参数。 它可以这样使用:

  1. import { Component, Inject } from '@angular/core';
  2. import { Hamburger } from '../services/hamburger';
  3. @Component({
  4. selector: 'app',
  5. template: `Bun Type: {{ bunType }}`
  6. })
  7. export class App {
  8. bunType: string;
  9. constructor(@Inject(Hamburger) h) {
  10. this.bunType = h.bun.type;
  11. }
  12. }

在上面示例中,我们要求chatWidget是单例的,Angular通过调用@Inject(ChatWidget)与类符号ChatWidget关联。 需要特别注意的是,我们使用ChatWidget的类型和作为其单例的引用。 我们没有使用ChatWidget来实例化任何东西,Angular在幕后帮我们做好了。

当使用TypeScript时,@Inject只需要注入primitives。 TypeScript的类型让Angular 2知道在大多数情况下要做什么。 以上示例将在TypeScript中简化为:

  1. import { Component } from '@angular/core';
  2. import { ChatWidget } from '../components/chat-widget';
  3. @Component({
  4. selector: 'app',
  5. template: `Encryption: {{ encryption }}`
  6. })
  7. export class App {
  8. encryption: boolean;
  9. constructor(chatWidget: ChatWidget) {
  10. this.encryption = chatWidget.chatSocket.encryption;
  11. }
  12. }

View Example

@Injectable()

@Injectable()让Angular 2知道一个类可以用于依赖注入器。 如果类上有其他Angular 2装饰器或没有任何依赖,@Injectable()不是必须的。

重要的是任何要注入Angular 2的类都被装饰。 然而,最佳实践是使用@Injectable()来装饰注入,因为它对开发者更强的语义。

这里有一个用@Injectable标记的 ChatWidget示例:

  1. import {Injectable} from '@angular/core';
  2. import {AuthService} from './auth-service';
  3. import {AuthWidget} from './auth-widget';
  4. import {ChatSocket} from './chat-socket';
  5. @Injectable()
  6. export class ChatWidget {
  7. constructor(public authService: AuthService, public authWidget: AuthWidget, public chatSocket: ChatSocket) {
  8. }
  9. }

在上面的例子中,Angular 2的注入器通过使用类型信息来确定要注入到ChatWidget的构造函数中。 这是可能的,因为这些特定的依赖关系是类型化的,并且不是原始类型。 在某些情况下,Angular 2的DI需要更多的信息,而不仅仅是类型。