Javascript 角度2-提供者实际上是如何工作的?
我一直在看官方Angular 2页面上的“英雄”教程,当我谈到路由时,有几件事没有意义。这是关于供应商的 有关部分的表述如下。我的主要组件如下所示:Javascript 角度2-提供者实际上是如何工作的?,javascript,angular,Javascript,Angular,我一直在看官方Angular 2页面上的“英雄”教程,当我谈到路由时,有几件事没有意义。这是关于供应商的 有关部分的表述如下。我的主要组件如下所示: /* app.components */ import {Component} from 'angular2/core'; import {HeroesComponent} from './heroes.component'; import {HeroService} from './hero.service'; @Component({
/* app.components */
import {Component} from 'angular2/core';
import {HeroesComponent} from './heroes.component';
import {HeroService} from './hero.service';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<my-heroes></my-heroes>
`
directives: [HeroesComponent],
providers: [HeroService]
})
export class AppComponent {
title = 'Tour of Heroes';
constructor(private _heroService: HeroService) {}
}
/* heroes.component */
import {Component} from 'angular2/core';
import {Hero} from './hero';
import {HeroDetailComponent} from './hero-detail.component';
import {HeroService} from './hero.service';
import {OnInit} from 'angular2/core';
@Component({
selector: 'my-heroes',
directives: [HeroDetailComponent],
template: `
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="#hero of heroes" [class.selected] = "hero === selectedHero" (click)="onSelect(hero)">
<span class="badge"> {{hero.id}} </span> {{hero.name}}
</li>
</ul>
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
`
})
export class HeroesComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
ngOnInit() {
this.getHeroes();
}
constructor(private _heroService: HeroService) { }
getHeroes() {
this._heroService.getHeroes().then(heroes => this.heroes = heroes);
}
onSelect(hero: Hero) {
this.selectedHero = hero;
}
}
/*app.components*/
从'angular2/core'导入{Component};
从“/heroses.component”导入{HeroesComponent};
从“/hero.service”导入{HeroService};
@组成部分({
选择器:“我的应用程序”,
模板:`
{{title}}
`
指令:[HeroesComponent],
提供者:[服务]
})
导出类AppComponent{
标题=‘英雄之旅’;
构造函数(私有_heroService:heroService){}
}
英雄组件如下所示:
/* app.components */
import {Component} from 'angular2/core';
import {HeroesComponent} from './heroes.component';
import {HeroService} from './hero.service';
@Component({
selector: 'my-app',
template: `
<h1>{{title}}</h1>
<my-heroes></my-heroes>
`
directives: [HeroesComponent],
providers: [HeroService]
})
export class AppComponent {
title = 'Tour of Heroes';
constructor(private _heroService: HeroService) {}
}
/* heroes.component */
import {Component} from 'angular2/core';
import {Hero} from './hero';
import {HeroDetailComponent} from './hero-detail.component';
import {HeroService} from './hero.service';
import {OnInit} from 'angular2/core';
@Component({
selector: 'my-heroes',
directives: [HeroDetailComponent],
template: `
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="#hero of heroes" [class.selected] = "hero === selectedHero" (click)="onSelect(hero)">
<span class="badge"> {{hero.id}} </span> {{hero.name}}
</li>
</ul>
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
`
})
export class HeroesComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
ngOnInit() {
this.getHeroes();
}
constructor(private _heroService: HeroService) { }
getHeroes() {
this._heroService.getHeroes().then(heroes => this.heroes = heroes);
}
onSelect(hero: Hero) {
this.selectedHero = hero;
}
}
/*heromes.component*/
从'angular2/core'导入{Component};
从“/Hero”导入{Hero};
从“./hero detail.component”导入{HeroDetailComponent};
从“/hero.service”导入{HeroService};
从'angular2/core'导入{OnInit};
@组成部分({
选择器:“我的英雄”,
指令:[HeroDetailComponent],
模板:`
我的英雄
-
{{hero.id}{{hero.name}
`
})
导出类HeroesComponent实现OnInit{
英雄:英雄[];
选择英雄:英雄;
恩戈尼尼特(){
这个。getheros();
}
构造函数(私有_heroService:heroService){}
getHeroes(){
this.\u heroService.getheromes().then(heromes=>this.heromes=heromes);
}
onSelect(英雄:英雄){
this.selectedHero=英雄;
}
}
好的,那么我的问题是:为了让它工作,我需要从“/hero.service”导入
import{HeroService}两个文件中的代码>。但是,提供者:[HeroService]
只是应用程序组件的@组件的一部分。我不需要在英雄.component中编写这段代码。heroes.component
如何知道选择哪个提供者?它是从应用程序组件继承的吗?如果是这样,为什么我必须在两个文件中都写这个:import{HeroService}from./hero.service'代码>?为什么不只是在应用程序组件中?这两个类也有相同的构造函数
。我不知道这里发生了什么,所以提前谢谢你的解释 喷油器是分层的。在bootstrap()
当Angular实例化一个类(服务、组件、管道等)时,它会请求DI实例,DI也会尝试解析构造函数参数。这是递归地完成的,直到不再需要解析其他依赖项,然后返回实例
从最近的注入器请求实例。如果注入器没有类型(或其他键,如字符串或OpaqueToken
)的提供程序,则请求将转发到父注入器,直到找到提供程序或到达根注入器
有关更多详细信息,请参见这与Angular2的“分层喷射器”功能有关。这些喷油器与部件相连,并遵循相同的树
子部件的喷油器是父部件的子喷油器。如果在当前注入器中找不到提供程序,将在父注入器中查找它
有关更多详细信息,请参见此问题:
在学习了Angular-2的一些文档之后,我分享了我关于依赖注入和提供者的知识,这些可以帮助别人
依赖项注入是分层的,并且
依赖项注入是一种重要的应用程序设计模式。Angular有自己的依赖注入框架,没有它我们真的无法构建Angular应用程序
依赖项是注入器范围内的单例。在我们的示例中,单个HeroService
实例在AppComponent
及其HeroComponent
子级之间共享
在您的示例中,AppComponent
是Heroes功能区的根组件。它管理此区域的所有子组件。YurHeroService
可能会公开一个返回heros数据的getheros
方法,但它的消费者都不需要知道这一点
服务只不过是Angular 2中的一个类。它仍然存在
只不过是一个类,直到我们用一个
注射器
这就是您需要配置喷油器的原因。我们不需要创建一个有角度的注入器。Angular在引导过程中为我们创建应用程序范围的注入器。我们必须通过注册创建应用程序所需服务的提供程序来配置注入器。我们可以在引导过程中注册提供程序。比如:
bootstrap(AppComponent,
[HeroService]); // DISCOURAGED (but works)
喷油器现在了解我们的服务
。我们的HeroService
的一个实例将可在整个应用程序中注入
首选的方法是在应用程序组件中注册应用程序提供者。因为HeroService
是在英雄功能区内使用的,而不是在其他地方使用的,所以注册它的理想位置是顶级heroscomponent
在组件中注册提供商
providers:[HeroService], // in your app.component that registers the HeroService
仔细查看组件
元数据的提供者
部分
HeroService
的一个实例现在可以在这个
AppComponent
及其所有子组件
AppComponent
本身