关于typescript:在Angular 2中的构造函数中声明服务实例

Declaring service instance inside constructor in Angular 2

我是新来的角度2和打字脚本,并试图了解DI。在我看到的所有代码中,我看到引用服务的变量都被输入到构造函数中。为什么会这样?为什么我们不能在构造函数外部而在类内部声明它呢?

请考虑以下英雄之旅的代码,例如在Angular网站上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { Component, OnInit } from '@angular/core';
import { Hero } from './hero';
import { HeroService } from './hero.service';

@Component({
    moduleId: module.id,
    selector: 'my-dashboard',
    templateUrl: `dashboard.component.html`,
    styleUrls: ['dashboard.component.css']
})
export class DashboardComponent implements OnInit {

    heroes: Hero[] = [];

    constructor(private heroService: HeroService) { }

    ngOnInit(): void {
        this.heroService.getHeroes()
            .then(heroes => this.heroes = heroes.slice(1, 5));
    }
}

如果我像下面这样在构造函数外部声明heroservice,应用程序会抛出许多错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
export class DashboardComponent implements OnInit {

    heroes: Hero[] = [];

    constructor() { }

    private heroService: HeroService;

    ngOnInit(): void {
        this.heroService.getHeroes()
            .then(heroes => this.heroes = heroes.slice(1, 5));
    }
}

据我所知,在构造函数外部编写它不会生成服务类HeroService的实例,但为什么呢?(是棱角分明的东西还是字体?)例如,Hero也是一个类(虽然不是服务类,但在技术上仍然是一个类!),我方已在施工单位外申报了heroes: Hero[] = [];,并已生效。


您在这里描述的是一个属性(setter)注入,理论上是可能的,但通常不建议将其视为一个坏的实践。

为了更好地理解这一点,您应该阅读一下构造函数注入以及为什么它比其他类型的注入(如属性注入)更受欢迎。

据我所知,Angular没有实现其他类型来强制开发人员使用最佳实践,这就是为什么您不能在构造函数之外使用它的原因。

角度1引用了这个文档,您可以阅读它来更深入地理解它。不要担心它来自以前的版本,这些概念术语与框架或语言无关,因此您可以阅读它来了解基础知识。

另外,不要忘记,在构造函数中使用变量的方式与在typescript中使用变量的方式(使用private时)会自动创建属性。所以当你把它放到一个构造器中时,angular会将它注入其中,typescripts会隐式地创建一个字段,就像在最后一个代码片段中那样,并从构造器参数初始化它。


Angular DI检查构造函数参数,当Angular DI创建类(服务、组件、指令、管道)的新实例时,它会查找要传递给构造函数的匹配提供程序。

因此,

  • 注入仅适用于由DI实例化的类

  • 只考虑注入的构造函数参数