2017-08-18 3 views
1

私はいくつかの "グローバル変数"(状態)を異なるコンポーネント間に保存する角型2のアプリケーションに取り組んでいます。これは、ユーザがyearcustomerIdなどを選択することができます。GET API /バックエンドの呼び出しで使用するには、すべてのコンポーネントがこれらのコンポーネントにアクセスする必要があります。角2: "グローバルパラメータサービス"を作成し、そのパラメータに登録する

私はルータパラメータを実装しているので、このようにパラメータをコンポーネントに渡すことは可能ですが、クリックするたびにルータ経由でパラメータを転送することによって状態を維持する必要がありません。これが理にかなってほしい。

とにかく、StackOverflowの上this質問に続いて、私は次のようserviceを設定している:

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/share'; 
import { Observer } from 'rxjs/Observer'; 

interface params { 
    year: string; 
    customerId: number; 
}; 

@Injectable() 
export class ParameterService { 

    // initial (test) values: 
    p: params = { 
     year: "2017", 
     customerId: 101 
    }; 

    constructor() {} 
} 

これは私のコンポーネントは、このようなパラメータを取得および設定することができ、2つの方法を動作するようです:

// get global value 
    this.year = this._parameterService.p['year']; 

    // set global value 
    this._parameterService.p['year'] = "2018"; 

データバインディングも機能します。これは、私が理解するように、stringyearに直接アクセスするのではなく、pがクラス(オブジェクト)であるためです。私はcomponent1からyear値を変更する場合は、component2(下)変更が反映されます:

<h1>Year = {{this._parameterService.p['year']}}</h1> 

私はそれを必要とするすべてのコンポーネントにParameterServiceを注入されて行う必要がある、と私は終わりだすべて。 しかし、変更されたパラメータで(別のGET呼び出しを実行)を再ロードするように、これをどのように拡張するかを理解できません。

ngOnInit(): void { 
    this.sub = this._route.params.subscribe(params => { 
     this.customerId = params['customerId']; 
     this.year = params['year']; 

     this.resetComponentState(); // based on new parameter this time 
    }); 
} 

resetComponentState(): void { 
    this._otherService.getDataFromApi(this.year) 
     .then(
     myData => this.myData = myData, 
     error => this.errorMessage = <any>error); 
} 

どのように基づいて同じことを達成することができます:ルータのパラメータの

は、コンポーネントは、ルート変更はいつでも、それは「リフレッシュ」させ、そのngOnInit方法でparamsに「サブスクライブ」 ParameterService?どういうわけかthis.yearthis._parameterService.p['year']と「バインド」することは可能ですか?resetComponentState()? Btw、I にはがやってみましたが、効果はありません。

import { Component, Input, OnInit } from '@angular/core'; 
import { MyData} from './mydata'; 
import { ActivatedRoute } from '@angular/router'; 
import { OtherService } from './other.service'; 
import { Observable } from 'rxjs/Observable'; 
import { Subject } from 'rxjs/Subject'; 
import { Headers, RequestOptions } from '@angular/http'; 
import { ParameterService } from '../parameter.service'; 
import { LocalStorageService } from 'angular-2-local-storage'; 

@Component({ 
    templateUrl: 'app/test/test.component.html' 
}) 

export class TestComponent implements OnInit { 

    subscription: any; 
    customerId: string; 

    // set getter as a property on the variable `year`: 
    ////year: string; 
    get year(): string { 
     console.log("test.component.get()"); 
     const value = this._parameterService.p['year'] + ""; 
     // Any other code you need to execute when the data is changed here 
     this.getDataFromApi(); 
     return value; 
    } 

    private sub: any; 

    errorMessage: string; 
    data: MyData[]; 
    constructor(private _otherService: OtherService, 
     private _parameterService: ParameterService, 
     private _route: ActivatedRoute, 
     private _localStorageService: LocalStorageService) { } 

    getDataFromApi() { 

     // store route parameters in Local Storage 
     // if none found, try reading from Local Storage 
     if (this.customerId == null) 
      this.customerId = this._localStorageService.get('customerId') + ""; 
     //if (this.year== null) 
     // this.year = this._localStorageService.get('year') + "";    

     this._localStorageService.set('customerId', this.customerId); 
     //this._localStorageService.set('year', this.year); 

     // try getting YEAR (not customerId, yet) from getter 
     this._otherService.getDataFromApi(this.customerId, this.year) 
      .then(
      data => this.data = data, 
      error => this.errorMessage = <any>error); 
    } 

    getData(): void{ 
     this.data = this._otherService.getData(); 
    } 

    resetComponentState(): void { 
     this.getDataFromApi(); 
    } 

    ngOnInit(): void { 

     this.sub = this._route.params.subscribe(params => { 
      this.customerId = params['customerId']; 
      //this.year = params['year']; 

      this.resetComponentState(); // based on new parameter this time 
     }); 
    } 
} 
+0

、私は設定/取得の両方持つことを示唆していると変数ごとに観測可能であるため、柔軟性が十分にあります。私はルートパラメータのためにこれを行うことをお勧めできません。それらはグローバルではなく、現在のルートに固有です。あなたはすでに 'route.params'を観測可能にしていますし、ActivatedRouteの' route.snapshot.params'オブジェクトを持っています。 – estus

+0

はい、多分私はものをovercomplicatingですか?ポイントは、一部のコンポーネントに日付ピッカーがあるため、ユーザーが年を変更すると、他のすべてのアクティブコンポーネントで年を更新するメカニズムが必要です。私が知っている限り、これは経路を通して行うことはできません。それでは、グローバルなサービスを求めていますか?もし私があなたを理解していれば、あなたは「グローバルなサービスを利用しますが、ルートパラメータに結びつけないでください。私の要点は、ルートを通じてコン​​ポーネントへの「ダイレクトリンク」もサポートしたいということです。しかし、 'year_param'やそのルートの何かを、同じ変数' year'ではなく使うことができますか? – joakimk

+0

したがって、 'mycomponent/2015/102'というルートを呼び出すことは、観測可能なルートとマッチすることができますが、それぞれ' year_param'と 'id_param'変数に入ります。これは変数 'year'のgetterと衝突しません。そして、ユーザーがURLで年間IDとIDを直接渡す場合、setterを介してグローバルサービスに値を設定(格納)することによって、このアプリケーション全体を反映させることができます。私は、コンポーネントの重複したリフレッシュを引き起こさないようにしなければなりません(最初はルートparamsから、次にグローバル・パラメーターが変更されてから2回目)。 – joakimk

答えて

0

使用ゲッターとセッター:

UPDATE は、ここで私は、パラメータの変化にリフレッシュする完全なコンポーネント(だけでなく、ルータパラメータの変更)です。このような何か:

// get global value 
get year() { 
    const value = this._parameterService.p['year']; 
    // Any other code you need to execute when the data is changed here 
    this.getDataFromApi(); 
    return value; 
} 

set year(value) { 
    this._parameterService.p['year'] = value; 
} 

私はここにこのことについてブログ記事を持っている:https://blogs.msmvps.com/deborahk/build-a-simple-angular-service-to-share-data/

そして、ここでplunker:一般的なグローバルサービスについてはhttps://plnkr.co/edit/KT4JLmpcwGBM2xdZQeI9?p=preview

+0

助けてくれてありがとう!私は一見したが、パラメータが変更されたときに、これがAPIへの新しい(リフレッシュされた)呼び出しをどのように引き起こすのかわかりません。ただし、データバインディング(テンプレート内の値を表示)はすでに動作しています。私は完全なコンポーネントで質問を更新しました。 'getDataFromApi()'の呼び出しで何とか 'getter'を呼び出すべきでしょうか? – joakimk

+0

または、 'getter'が' getDataFromApi'を呼び出すべきですか?(あなたのコメントによると、「データがここで変更されたときに実行する必要のある他のコード」)? – joakimk

+0

はい、2番目です。データがチェックされると、Angularの変更検出によって変更が認識され、ゲッターを呼び出して値を再取得します。次に、データが変更されたときに実行する必要のあるコードを追加できます。試してみてください... – DeborahK

関連する問題