Angular2 Heros教程-子组件如何获得服务/提供者?

Angular2 Heros教程-子组件如何获得服务/提供者?,angular,Angular,我现在正在学习Angular2 Heros教程 我特别: 返回HeroesComponent并从其提供程序阵列中删除HeroService。我们正在将此服务从HeroesComponent升级到AppComponent。我们不希望在我们的应用程序的两个不同级别上使用此服务的两个副本 app.comont.ts: import { Component } from '@angular/core'; import { HeroService } from './hero.service'; impo

我现在正在学习Angular2 Heros教程

我特别:

返回HeroesComponent并从其提供程序阵列中删除HeroService。我们正在将此服务从HeroesComponent升级到AppComponent。我们不希望在我们的应用程序的两个不同级别上使用此服务的两个副本

app.comont.ts:

import { Component } from '@angular/core';
import { HeroService } from './hero.service';
import { HeroesComponent } from './heroes.component';

@Component({
    selector: 'my-app',
    template: `
            <h1>{{title}}</h1>
            <my-heroes></my-heroes>
    `,
    directives: [HeroesComponent],
    providers: [
        HeroService
    ]

})
export class AppComponent { 
    title = 'Main App';
}
我的问题是,当我从heros.components中的提供者列表中删除heros服务时,为什么这仍然有效

我的假设是,由于我们在构造函数中指定需要一个HeroService,因此父组件(在本例中为app.component)将提供一个HeroService。这准确吗

providers数组告诉Angular在创建新的AppComponent时创建HeroService的新实例。AppComponent可以使用该服务获取英雄,其组件树的每个子组件也可以。

所以你的假设部分是正确的。 实际上,您的
app.component
一旦被子组件注入,就会创建一个服务实例。由于您的
hero.component
app.component
的子组件,因此它将使用相同的实例。所以不仅仅是一个,而是一个

如果您多次实例化一个服务,那么了解这种行为以避免错误是非常重要的,而这可能不是您大多数时候想要的


更新更多信息: 正如Mark Rajcok在其评论中正确指出的,只要
app.component
的子组件之一注入服务,就会创建该服务。如果没有子组件注入服务,则不会创建该服务的实例


正如Ed Morales所补充的,通过使用
viewProviders
而不是
providers
来提供服务还有另一种可能性,这将使创建的实例只能由提供组件访问,而不是对其所有子代进行访问。

providers
数组注册一个类(或函数、预定义对象或字符串)带有组件注入器。例如

providers: [HeroService]
constructor(private heroService: HeroService)
这实际上是一个简单的表达

providers: [new Provider(HeroService, {useClass: HeroService})]
本质上,我们向注入器注册一个“配方”——即,我们告诉注入器当此组件或其子组件之一注入
HeroService
时如何创建
HeroService
(即依赖项)

我们使用构造函数注入依赖项。例如

providers: [HeroService]
constructor(private heroService: HeroService)
HeroesComponent
注入
HeroService
时,Angular执行以下操作:

  • 它首先查看请求组件的注入器(即,
    HeroesComponent
    的注入器)是否有创建
    HeroService
    的方法。它没有(它不在其
    提供程序
    数组中),因此它会沿着组件树向上移动到其父组件
  • 然后检查父组件的注入器(即
    AppComponent
    的注入器)是否有创建
    HeroService
    的方法。它有。然后
    AppComponent
    注入器执行以下操作:
    • 如果它以前创建了
      HeroService
      的实例,则返回对它的引用
    • 否则(即,这是第一个注入/请求服务的组件),它将执行以下操作:
      • 它使用配方创建
        HeroService
        的实例
      • 它存储对它的引用(对于此依赖项的其他可能请求)
      • 它返回对请求依赖项的
        HeroesComponent
        的引用

AppComponent
的注入器将只创建一个
HeroService
的实例实例可以注入到
AppComponent
和/或其任何子体中。

是的,再加上一个问题:
providers
数组与子组件共享实例,而
viewProviders
数组只为该组件及其模板创建实例。我认为文档没有那么正确idersarray向组件的注入器注册提供程序。创建AppComponent时不会创建HeroService。当子组件(在其构造函数中)注入器时会创建HeroService。从中删除
,您将看到服务的实例不会创建,因为没有组件将其注入器。