我现在正在阅读Angular2 Heros教程。
我具体是at this step:
返回HeroesComponent并从其providers数组中删除HeroService。我们正在将这项服务从HeroesComponent推广到AppComponent。我们不希望在我们的应用程序的两个不同级别上提供此服务的两个副本。
app.comonent.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.component.ts:
import { Component, OnInit } from '@angular/core';
import { Hero } from './hero';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroService } from './hero.service';
@Component({
selector: 'my-heroes',
template: `
... bla bla bla ...
`,
styles:[`
... bla bla bla ...
`],
directives: [HeroDetailComponent],
providers: [
HeroService
]
})
export class HeroesComponent implements OnInit {
public heroes: Hero[];
selectedHero: Hero;
constructor(
private heroService: HeroService
){}
ngOnInit() {
this.heroService.getHeroes().then( heroes => this.heroes = heroes );
}
onSelect = function (hero: Hero){
this.selectedHero = hero;
}
}
我的问题是,当我从heros.components的Providers列表中删除HeroService时,为什么这仍然有用?
我的假设是,因为我们在构造函数中指定我们需要一个HeroService,一个将由父组件提供(在本例中为app.component)。这准确吗?
答案 0 :(得分:5)
providers数组告诉Angular在创建新的AppComponent时创建一个新的HeroService实例。 AppComponent可以使用该服务来获取英雄,因此可以使用其组件树的每个子组件。
所以你的假设是部分正确的。
实际上,您的app.component
会在子组件注入后立即创建一个服务实例。由于您的hero.component
是app.component
的孩子,因此它将使用相同的实例。所以不是只有一个,而是那个。
如果您多次实例化服务,那么知道该行为可以避免错误,这可能不是您想要的大部分时间。
正如Mark Rajcok在他的评论中正确指出的那样,只要app.component
的一个子组件注入它,就会创建该服务。如果没有子组件注入该服务,则不会创建该服务的实例。
正如Ed Morales补充的那样,通过使用viewProviders
代替providers
来提供服务还有另一种可能性,这将使得创建的实例只能由提供组件访问,而不是所有它的孩子。
答案 1 :(得分:3)
providers
数组使用组件注入器注册类(或函数,或预定义对象或字符串)。例如,
providers: [HeroService]
这实际上是
的简写表达式providers: [new Provider(HeroService, {useClass: HeroService})]
基本上我们注册了一个&#34;配方&#34;使用注入器 - 即,当该组件或其后代之一注入HeroService
时,我们告诉注入器如何创建HeroService
(即依赖)。
我们使用构造函数注入依赖项。例如,
constructor(private heroService: HeroService)
当HeroesComponent
注入HeroService
时,Angular执行以下操作:
HeroesComponent
注入器)是否具有用于创建HeroService
的配方。它没有(它不在它的providers
数组中),所以它将组件树上升到它的父组件。 AppComponent
注射器)是否具有用于创建HeroService
的配方。确实如此。 AppComponent
注入器然后执行以下操作:
HeroService
的实例,则返回对它的引用。HeroService
的第一个组件),它执行以下操作:
HeroService
。HeroesComponent
。 AppComponent
的注射器只会创建HeroService
的一个实例。该(一个)实例可以注入AppComponent
和/或其任何后代。