在Angular 2中声明构造函数内的服务实例

时间:2017-01-18 09:11:26

标签: angular typescript

我是Angular 2和Typescript的新手并试图了解DI。在我看到的所有代码中,我看到引用服务的变量被输入到构造函数中。这是为什么?为什么我们不能在构造函数之外但在类中声明它?

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

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,那么应用程序会抛出许多错误。

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的实例,但为什么呢? (它是一个Angular的东西还是TypeScript?)在这个例子中,Hero也是一个类(虽然不是服务类,但在技术上仍然是一个类!),我们在构造函数之外声明了heroes: Hero[] = []; ,它的确有效。

2 个答案:

答案 0 :(得分:1)

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

因此,

  • 注射仅适用于DI

  • 实例化的分类
  • 只考虑构造函数参数进行注入

答案 1 :(得分:1)

你在这里描述的是属性(二传手)注射,理论上是可能的,但通常不推荐,也被认为是一种不好的做法。

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

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

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

P.S。不要忘记在构造函数中使用Typescript中的变量(使用private)会自动创建属性。因此,当您在构造函数中使用它时,Angular会将其注入其中,而Typescripts会隐式创建一个字段,就像在上一个代码段中一样,并从构造函数参数初始化它。