Angular 4依存注入チュートリアルの7 ValueProviderの使用


目次
  • Angular 4依存注入チュートリアルの1つ依存注入概要
  • Angular 4依存注入チュートリアルの2コンポーネントサービス注入
  • Angular 4依存注入チュートリアルの3 ClassProviderの使用
  • Angular 4依存注入チュートリアルの4 FactoryProviderの使用
  • Angular 4依存注入チュートリアルの5 FactoryProvider構成依存オブジェクト
  • Angular 4依存注入チュートリアルの6 Injectableアクセサリ
  • Angular 4依存注入チュートリアルの7 ValueProviderの使用
  • Angular 4依存注入チュートリアルの8 InjectTokenの使用
  • 読書の心得
    このチュートリアルの開発環境と開発言語:
  • Angular 4 +
  • Angular CLI
  • TypeScript

  • 基礎知識
    ValueProviderの役割
    ValueProviderはInjector(インジェクタ)に伝えますが、Tokenを使用して依存オブジェクトを取得すると、useValueで指定した値が返されます.
    ValueProviderの使用
    const provider: ValueProvider = {provide: 'someToken', useValue: 'someValue'};

    ValueProviderインタフェース
    export interface ValueProvider {
      //             Token ,Token    Type、InjectionToken、
      // OpaqueToken       
      provide: any;
      //        
      useValue: any;
      //       multiple providers,  multiple  ,    Token     
      //     
      multi?: boolean;
    }

    json-serverの概要
    json-serverは、JSONデータに基づいてローカルシミュレーションのREST APIを迅速に作成するために使用される.
    json-serverのインストール
    npm install -g json-server

    json-serverの使用
    json-server --watch db.json

    Angular CLIエージェント構成proxy.conf.jsonファイルの作成
    {
      "/heros": {
        "target": "http://localhost:3000",
        "secure": false
      }
    }
    package.jsonファイルの更新
    {
      "scripts": {
        "start": "ng serve --proxy-config proxy.conf.json",
      }
    }

    ValueProvider
    基礎知識を紹介したら、すぐに本題に入ります.「コンポーネント・サービス・インジェクション」の記事で述べた内容を覚えていますか.
    まさかすべてが終わったのか、No!No!この授業のテーマは、コンポーネントにサービスを注入する方法を紹介することです.現在のHeroComponentコンポーネントでは、ヒーローリスト情報は固定されており、実際の開発シーンでは、リモートサーバから対応する情報を取得する必要があります.
    次に、HeroServiceサービスを再構築し、APIインタフェースからヒーローデータを取得します.AngularのHttpサービスを使用するには、まずAppModuleモジュールにHttpModuleを導入し、HeroServiceクラスのコンストラクタにHttpサービスを注入する必要がある.
    HeroServiceサービスの更新
    import { Injectable } from '@angular/core';
    import { Http } from '@angular/http';
    
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/operator/map';
    
    import { LoggerService } from './logger.service';
    
    @Injectable()
    export class HeroService {
        constructor(private loggerService: LoggerService,
          private http: Http) { }
    
        apiUrl = 'http://localhost:4200/heros';
    
        getHeros(): Observable> {
            this.loggerService.log('Fetching heros...');
            return this.http.get(this.apiUrl)
                .map(res => res.json())
        }
    }
    HeroServiceサービスでは、Httpサービスオブジェクトを注入するget()方法によってHTTP要求を送信し、APIインタフェースからヒーローのデータを取得する.
    HeroComponentコンポーネントの更新
    import { Component, OnInit } from '@angular/core';
    import { HeroService } from '../hero.service';
    import { LoggerService } from '../logger.service';
    
    @Component({
      selector: 'app-hero',
      template: `
        
    • ID: {{hero.id}} - Name: {{hero.name}}
    ` }) export class HeroComponent implements OnInit { heros: Array; constructor(private heroService: HeroService, private loggerService: LoggerService) { } ngOnInit() { this.loggerService.log('Fetching heros...'); this.heroService.getHeros() .subscribe(res => { this.heros = res; }); } }

    上記のコードを更新し、保存に成功すると、http://localhost:4200/ページが空白になります.これは正しいです.ローカルのjson-serverサーバがまだ起動していないからです.次に、ローカルのjson-serverサーバを構成して起動します.heros.jsonファイルの作成
    {
      "heros": [
        {"id":11,"name":"Mr. Nice"},
        {"id":12,"name":"Narco"},
        {"id":13,"name":"Bombasto"},
        {"id":14,"name":"Celeritas"},
        {"id":15,"name":"Magneta"}
     ]
    }
    json-serverサーバの起動
    json-server --watch heros.json
    json-serverサーバが正常に起動すると、コマンドラインに次の出力情報が表示されます.
    \{^_^}/ hi!
    
    Loading heros.json
    Done

    これは、ローカルjson-serverが正常に起動したことを示しています.このとき、次のhttp://localhost:4200/ページを再リフレッシュします.次の情報が表示されます.
    ID: 11 - Name: Mr. Nice
    ID: 12 - Name: Narco
    ID: 13 - Name: Bombasto
    ID: 14 - Name: Celeritas
    ID: 15 - Name: Magneta

    プログラムはついに正常に動作したが、HeroServiceサービスでは、APIインタフェースアドレスを以下の方法で定義していることに気づいた.
    @Injectable()
    export class HeroService {
      ...
      apiUrl = 'http://localhost:4200/heros';
    }

    この方法には、他のサービスもアドレスを使用すると仮定すると、APIインタフェースアドレスを同様に定義しなければならないという問題がある.また、APIインタフェースアドレスを更新する必要があると仮定すると、複数の箇所を修正する必要がある.上記の問題に対して、ValueProviderを使用して問題を解決することができます.
    ValueProviderの使用
    @NgModule({
       ...,
       providers: [
        {
          provide: 'apiUrl',
          useValue: 'http://localhost:4200/heros'
        }
       ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

    HeroServiceサービスの更新
    @Injectable()
    export class HeroService {
        constructor(private loggerService: LoggerService,
            private http: Http,
            @Inject('apiUrl') private apiUrl) { }
    
        getHeros(): Observable> {
            this.loggerService.log('Fetching heros...');
            return this.http.get(this.apiUrl)
                .map(res => res.json())
        }
    }
    HeroServiceクラスの構造関数では、@Inject('apiUrl')方式により、apiUrlに対応する依存オブジェクト、すなわちTokenを注入する.なぜ'http://localhost:4200/heros'を使えないのか、前に紹介した内容をよく思い出してほしい.
    上記のコードが正常に実行された後、private apiUrl: 'apiUrl'ページで予想される結果が表示されます.
    ID: 11 - Name: Mr. Nice
    ID: 12 - Name: Narco
    ID: 13 - Name: Bombasto
    ID: 14 - Name: Celeritas
    ID: 15 - Name: Magneta

    話があるんだ
    なぜコンストラクション関数でTypeタイプ以外のパラメータは@Inject(Something)でしか注入できないのですか?http://localhost:4200/タイプのオブジェクトは、Typeコンパイラによってコンパイルされるためです.すなわち、TypeScriptキーワードで宣言されたサービスは、最終的にはclassの関数オブジェクトにコンパイルされます.
    コンストラクション関数でTypeタイプのパラメータを@Inject(Type)で注入できますか?ES5型のパラメータもTypeの方式で注入することができ、具体的には以下の通りである.
     constructor(@Inject(Http) private http) { }

    次の方法も使用できます.
    constructor(@Inject(Http) private http: Http) { }

    1つ目の方法は正常にコンパイルできますが、IDEには次のようなヒントがあります.
    [ts] Parameter 'http' implicitly has an 'any' type.

    2つ目は、Angular内部でdesign:paramtypesとparameters内のmetadata情報が統合されますが、本人は少し冗長だと思います.要するに、Typeタイプのパラメータであれば、以下の方法を推奨します.
    constructor(private http: Http) { }
    @Inject(Type)デコレーションの詳細については、Angular 2 Injectを参照してください.