Angular 2中为何需通过构造函数注入服务?构造函数作用解析
关于Angular构造函数注入的疑问解答
先贴出你提供的代码方便参考:
import { Component, OnInit } from '@angular/core'; import { FormGroup,FormsModule,FormControl } from '@angular/forms'; import { WeatherService } from '../weather.service'; import { WeatherItem } from '../weather-item'; @Component({ selector: 'app-weather-search', templateUrl: './weather-search.component.html', styleUrls: ['../../assets/app.css'], //providers: [WeatherService] }) export class WeatherSearchComponent implements OnInit { constructor(private _weatherService : WeatherService) { } onSubmit(form : FormGroup){ //alert(form.value.location); this._weatherService.searchWeatherData(form.value.location) .subscribe( data => { const weatherItem = new WeatherItem(data.data.request["0"].query,data.data.weather["0"].maxtempC,data.data.weather["0"].maxtempC); this._weatherService.addWeatherItems(weatherItem); console.log(form); }) } ngOnInit() { } }
1. 能不能在构造函数外部完成依赖注入?
理论上可以,但非常不推荐。
如果你想绕开构造函数,可以通过Angular的Injector手动获取服务实例,比如在ngOnInit里:
import { Component, OnInit, Injector } from '@angular/core'; export class WeatherSearchComponent implements OnInit { private _weatherService: WeatherService; constructor(private injector: Injector) { } ngOnInit() { // 手动从注入器中获取WeatherService实例 this._weatherService = this.injector.get(WeatherService); } }
这种方式会让代码耦合度变高,而且单元测试时模拟依赖会更麻烦,完全没必要这么做。
另外,Angular 6+支持属性注入的简写,看起来像是脱离了构造函数,但本质还是依赖构造函数的DI系统:
import { Inject } from '@angular/core'; export class WeatherSearchComponent implements OnInit { // 直接在属性上使用@Inject装饰器 @Inject(WeatherService) private _weatherService: WeatherService; constructor() { } // 构造函数可以是空的 }
不过这种写法也不如构造函数注入直观,社区还是更推荐构造函数注入的方式。
2. 构造函数在这里的实际作用是什么?
在Angular组件中,构造函数的核心作用就是作为依赖注入的入口:
- 当Angular创建你的
WeatherSearchComponent实例时,会自动解析构造函数中的参数(这里是WeatherService),从依赖注入容器中取出对应的服务实例,传递给组件。 - 你写的
private _weatherService : WeatherService是TypeScript的语法糖,等价于先声明私有属性,再在构造函数里赋值,大大简化了代码。 - 注意:构造函数只适合做依赖注入和极简单的初始化(比如给属性赋默认值),复杂的初始化逻辑(比如调用服务获取数据)应该放在
ngOnInit里,因为此时组件的输入属性已经完成绑定。
3. 我们真的需要在这里使用构造函数注入吗?
是的,这是Angular官方推荐的最优实践,原因有这些:
- 代码可读性高:一眼就能看出这个组件依赖哪些服务,维护起来更方便。
- 便于单元测试:测试框架可以轻松地模拟
WeatherService的实例,验证组件的行为。 - 符合Angular的设计理念:依赖注入是Angular的核心特性之一,构造函数注入是最自然、最规范的使用方式,团队协作时大家都能快速理解代码。
总的来说,构造函数注入是Angular中获取服务依赖的标准方式,完全没必要刻意绕开它~
内容的提问来源于stack exchange,提问作者user3760959
相关产品推荐
相关产品推荐

