Angular 入门基础(第十二篇) Angular 中的依赖注入

160 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天。点击查看活动详情

依赖项是指某个类执行其功能所需的服务或对象。依赖项注入(DI)是一种设计模式,在这种设计模式中,类会从外部源请求依赖项而不是创建它们。

Angular 的 DI 框架会在实例化某个类时为其提供依赖。可以使用 Angular DI 来提高应用程序的灵活性和模块化程度。

创建可注入服务

要想在 src/app/heroes 目录下生成一个新的 HeroService 类,请使用下列 Angular CLI 命令。

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

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

@Injectable() 装饰器会指定 Angular 可以在 DI 体系中使用此类。元数据 providedIn: 'root' 表示 HeroService 在整个应用程序中都是可见的。

接下来,要获取英雄的模拟数据,请添加一个 getHeroes() 方法,该方法会从 mock.heroes.ts 中返回英雄。

import { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes';

@Injectable({
  // declares that this service should be created
  // by the root application injector.
  providedIn: 'root',
})
export class HeroService {
  getHeroes() { return HEROES; }
}

为了清晰和可维护性,建议你在单独的文件中定义组件和服务。

如果你确实要将组件和服务合并在同一个文件中,则必须先定义服务,再定义组件,这一点很重要。如果在服务之前定义组件,Angular 将返回运行时的空引用错误。

注入服务

注入某些服务会使它们对组件可见。

要将依赖项注入组件的 constructor() 中,请提供具有此依赖项类型的构造函数参数。下面的示例在 HeroListComponent 的构造函数中指定了 HeroService。heroService 的类型是 HeroService。

constructor(heroService: HeroService)

在其他服务中使用这些服务 当某个服务依赖于另一个服务时,请遵循与注入组件相同的模式。在这里,HeroService 要依靠 Logger 服务来报告其活动。

首先,导入 Logger 服务。接下来,通过在括号中指定 private logger: Logger,来在 HeroService 的 constructor() 中注入 Logger 服务。

当创建一个其 constructor() 带有参数的类时,请指定其类型和关于这些参数的元数据,以便 Angular 可以注入正确的服务。

在这里,constructor() 指定了 Logger 的类型,并把 Logger 的实例存储在名叫 logger 的私有字段中。

下列代码具有 Logger 服务和两个版本的 HeroService。HeroService 的第一个版本不依赖于 Logger 服务。修改后的第二个版本依赖于 Logger 服务。

import { Injectable } from '@angular/core';
import { HEROES } from './mock-heroes';
import { Logger } from '../logger.service';

@Injectable({
  providedIn: 'root',
})
export class HeroService {

  constructor(private logger: Logger) {  }

  getHeroes() {
    this.logger.log('Getting heroes ...');
    return HEROES;
  }
}
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class Logger {
  logs: string[] = []; // capture logs for testing

  log(message: string) {
    this.logs.push(message);
    console.log(message);
  }
}