Angular通过依赖注入机制注入一个对象的例子

108 阅读1分钟

假设我在app.config.ts里定义了一个interface AppConfig和一个对象HERO_DI_CONFIG, 我想将后者注入到一个类的构造函数里去:

export interface AppConfig {
    apiEndpoint: string;
    title: string;
  }

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

export const APP_CONFIG = new InjectionToken<AppConfig>('app.config');

export const HERO_DI_CONFIG: AppConfig = {
  apiEndpoint: 'api.heroes.com',
  title: 'Dependency Injection'
};

使用InjectionToken新建一个token,类型参数为AppConfig,单引号里的app.config是injection token的描述信息。

在NgModule里使用useValue注入:

在需要使用这个依赖的地方,将token APP_CONFIG传入@Inject:

最后的效果:


在控制反转中,”控制“是指对程序流程的控制,”反转“则是将控制权从程序员的手里反转到了外层框架。

@optional修饰符

@Component({
  selector: 'app-notification',
  templateUrl: './notification.component.html',
  styleUrls: ['./notification.component.less']
})
export class NotificationComponent implements OnInit {
  constructor(@Optional() private msg: MessageService) {}

  ngOnInit() {
    this.msg.send();
  }
}

如果无法注入,msg被Angular解析成null,而不会抛出错误。

@Optional() 允许 Angular 将您注入的服务视为可选服务。这样,如果无法在运行时解析它,Angular 只会将服务解析为 null,而不会抛出错误

@Self

使用 @Self 让 Angular 仅查看当前组件或指令的 ElementInjector

@SkipSelf

使用 @SkipSelf(),Angular 在父 ElementInjector 中而不是当前 ElementInjector 中开始搜索服务

一个例子:在父组件中定义了一个服务:ParentMessageService

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

@Injectable({
  providedIn: 'root'
})
export class ParentMessageService {
  constructor() {}

  send() {
    console.log('come from parent');
  }
}

@Component({
  selector: 'app-container',
  templateUrl: './container.component.html',
  styleUrls: ['./container.component.less'],
  providers: [
    { 
      provide: MessageService, 
      useClass: ParentMessageService 
    }
  ]
})
export class ContainerComponent implements OnInit {
  constructor() {}

  ngOnInit() {}
}

子组件中,我们已提供了服务,但是注入时使用了 @SkipSelf() 修饰符

@Component({
  selector: 'app-notification',
  templateUrl: './notification.component.html',
  styleUrls: ['./notification.component.less'],
  providers: [
    {
      provide: MessageService,
      useClass: NewMessageService
    }
  ]
})
export class NotificationComponent implements OnInit {
  constructor(@SkipSelf() private msg: MessageService) {}

  ngOnInit() {
    this.msg.send();
  }
}

最终,Angular会注入父组件的服务实例:ParentMessageService
要获取更多Jerry的原创文章,请关注公众号"汪子熙":