2016-04-18 15 views
2

私は公式のAngular 2ページで "Heroes"チュートリアルを行ってきました。ルーティングに着いたときには、いくつかのことは意味をなさないものでした。それはプロバイダに関するものです。角度2 - プロバイダは実際にどのように機能しますか?

この部分は次のように表されます。私の主なコンポーネントは次のようになります。

/* 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; 
    } 

} 

はOK、そう、私の質問:これが機能するためには、私は両方のファイルにimport {HeroService} from './hero.service';をインポートする必要が

/* 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) {} 
} 

や英雄のコンポーネントは次のようになります。しかし、providers: [HeroService]@Componentの一部分にすぎず、app.componentsの一部に過ぎません。私はこのコードをheroes.componentに書く必要はありません。 heroes.componentはどのプロバイダを選ぶべきでしょうか?それはapp.componentsから継承されていますか?もしそうなら、私はなぜこれを両方のファイルに書く必要がありましたか:import {HeroService} from './hero.service';?なぜapp.componentsに入っていないのですか?どちらのクラスも同じconstructorを持っています。私はここで何が起こっているのか分からないので、事前の説明に感謝します。

答えて

0

インジェクタは階層型です。 bootstrap()では、ルートプロバイダが初期化され、各コンポーネントに対して別の子インジェクタが作成され、DOM内のコンポーネントを模倣する構造になります。

アングルでは、クラス(サービス、コンポーネント、パイプなど)をインスタンス化すると、DIおよびDIのインスタンスにコンストラクタパラメータの解決を試みます。これは、それ以上の依存関係を解決する必要がなくなるまで再帰的に行われ、インスタンスが返されます。

インスタンスは、最も近いインジェクタから要求されます。インジェクタにタイプ(または文字列またはOpaqueTokenなどの他のキー)のプロバイダがない場合、リクエストはプロバイダが見つかるか、ルートインジェクタに達するまで親インジェクタに転送されます。詳細については

https://angular.io/docs/ts/latest/api/core/Directive-decorator.html

0

これはAngular2の「階層インジェクタ」機能にリンクされているを参照してください。これらのインジェクタはコンポーネントにリンクされ、同じツリーに従います。

子コンポーネントのインジェクタは、親コンポーネントのサブインジェクタです。プロバイダは現在のインジェクタに見つからない場合、それは親の一つに探されます...

は、詳細については、この質問を参照してください:

0

はい、継承され、インジェクタは階層型です。このブログのpostと公式documentationを確認してください。

0

の角膜2のドキュメントを勉強した後、角度2私はdependency-injection and providersについて知りましたが、誰かを助けるかもしれません。

依存性の注入は階層的であると 依存性の注入は、重要なアプリケーションのデザインパターンです。Angularには独自の依存関係注入フレームワークがあり、実際にはAngularアプリケーションを構築することはできません。

依存関係は、インジェクタのスコープ内のシングルトンです。この例では、単一のHeroServiceインスタンスがAppComponentとその子どものHeroComponentの間で共有されています。

例では、AppComponentはヒーローズ機能領域のルートコンポーネントです。この領域のすべての子コンポーネントを管理します。 Yur HeroServiceは、ヒーローデータを返すメソッドを公開するかもしれませんが、消費者の誰もそれを知る必要はありません。

サービス私たちは、角 インジェクタに登録するまでは、クラスよりも 何も残っていない角度2のクラス以外の何ものでもありません。あなたは、インジェクタを設定する必要がある理由です

。 Angularインジェクタを作成する必要はありません。 Angularは、ブートストラッププロセス中にアプリケーション全体のインジェクタを作成します。プロバイダを登録してインジェクタを設定する必要があります。アプリケーションに必要なサービスを作成します。以下のように:

bootstrap(AppComponent, 
     [HeroService]); // DISCOURAGED (but works) 

インジェクタは、今、私たちHeroServiceについて知っています。 HeroServiceのインスタンスは、アプリケーション全体に注入することができます。

好ましい方法は、アプリケーションコンポーネントをアプリケーションコンポーネントに登録することです。 HeroServiceはHeroes機能領域内で使用されているため、登録するのに理想的な場所はHeroesComponentです。コンポーネント

providers:[HeroService], // in your app.component that registers the HeroService 

でプロバイダを登録

@Componentメタデータのproviders部分をよく見ます。

HeroServiceのインスタンスは、この AppComponentの注射およびその子コンポーネントのすべてのために利用できるようになりました。

AppComponent自体には、HeroServiceは必要ありません。しかし、 その子供HeroComponentがあります。

コンストラクタにパラメータを追加するコンストラクタを中心

constructor(private _heroService: HeroService) { 
    this._heroService.getHeroes().then(heroes => this.heroes = heroes); // or you can use in OnInit 
} 

N.B:はあなたのappComponent

constructorを使用する必要私たちは、活字体で書いていないしている可能性がありと 型注釈、:HeroServiceでパラメータ名に従っています。また、クラスは @Componentデコレータで飾られています。

TypeScriptコンパイラがこのクラスを評価すると、 @Componentデコレータが表示され、生成された JavaScriptコードにクラスメタデータが追加されます。そのメタデータの中には、 がheroServiceパラメータをHeroServiceクラスに関連付けるという情報が潜んでいます。

これは、 HeroServiceのインスタンスを挿入する方法をAngularインジェクタが知っているので、新しいHeroComponentが作成されます。依存性注入のための

詳細は

および階層依存性注入のためのthis linkが見ることができる見ることができますthis link

関連する問題