2017-02-17 10 views
1

私はアプリケーションでinternatiolizationをやっています。親コンポーネントの内部には多くのコンポーネントがあります。次のように私は、現在選択された通貨を設定していますapp.component.tsで親コンポーネントに変数の変更を通知するにはどうすればいいですか?

ngOnInit() {  
    this.selectedLanguage = "EN"; 
    this.selectedCurrency = "EUR"; 
    //also setting to local storage 
    localStorage.setItem('currency', this.selectedCurrency); 
} 

あり、私はパイプにselectedcurrencyを使用する必要があり、別の子コンポーネントがあるので、私は取得しています

export class EveComponent implements OnInit { 
    selectedCurrency :string; 
    ngOnInit() { 
     this.selectedCurrency = localStorage.getItem("currency"); 
    } 
} 

を次のように中selectedcurrencyが、変更が親で起きたときに、これは、動作しているようですしません。私は私の親ページのselectedCurrencyを変更したとき と私のパイプ次のように、

<div class="price">{{123 | currConvert | currency:selectedCurrency:true:'3.2-2'}}</div> 

は今、私はそれが同様にEveComponentに適用することにしたいです。どのようにangular2でそれを行うには?

答えて

2

1 - あなたの子コンポーネントがappComponentの直接の子である場合、子に@Inputを使用できるはずです。

親コンポーネントテンプレート:

<child-cmp [selectedCurrency]="selectedCurrency"></child-cmp> 

、その後、子コンポーネント

export class EveComponent implements OnInit { 
    @Input() selectedCurrency :string; 
} 

に子供にはもうあなたのlocalStorageサービスを使用する必要はありません内部。

2 - 子コンポーネントが、この場合には、あなたが持つEventEmitterを作成することができ、親コンポーネントの直接の子ではない:あなたの中

のlocalStorageサービス:

export class LocalStorageService{ 
    $currencyChanges = new EventEmitter<any>(); 

    public setItem(item){ 
     // what ever u where doing , plus : 
     this.$currencyChanges.emit(item); 
    } 
} 

そして、子供の中には既にサービスがあるので、できる:

エクスポートクラスEveComponentはOnInit {

を実装しています
ngOnInit() { 
    localStorage.$currencyChanges.subscribe((changes)=>{ 
     this.selectedCurrency = changes; 

    }); 
} 
+0

LocalStorageServiceはそのサービスではありませんコンポーネント – Sajeetharan

+0

これをどのように変更する必要がありますか? $ currencyChangesが見つからないというエラーが表示される – Sajeetharan

+0

localStorageはサービスではありません。それは何ですか?コードを共有できますか? – Milad

1

ngOnInit()でモデルを変更することは、通常はお勧めできません。 ngOnInit()が変更検出によって呼び出され、変更検出中に変更されると、通常、「式がチェックされた後に式が変更されました」のような問題が発生します。

これは、より良い動作するはず:

constructor() { 
    this.selectedCurrency = localStorage.getItem("currency"); 
} 

コードをコンストラクタの中でも(テストと同じように)いくつかの欠点があります。その標準はParent-> Child通信やsibling->sibling通信のためのケースのようにように思えるあなたの質問を1として

別の回避策は、したがって、

constructor(private cdRef:ChangeDetectorRef) {} 

ngOnInit() { 
    this.selectedCurrency = localStorage.getItem("currency"); 
    this.cdRef.detectChanges(); 
} 
+0

それが動作しない – Sajeetharan

+0

'localStorage.getItem(...)'が実際に値を取得しているかどうかを確認してください。他のコンポーネントがまだそれを設定できなかった可能性があります。 –

+0

デフォルトで設定されているのと同じ値を取得します。ドロップダウンを変更して親ページに設定したときに値を設定したい場合 – Sajeetharan

0

です。

は、私はあなたが[少なくとも currency用]の値(およびその観測できない)

は、あなたが治療しようとしましたためsharedServiceとして「のlocalStorage」を使用しようとしている意味ローカルストレージにcurrencyを保存していることを観察しましたselectedCurrencyを入力としてchildparentCurrencyに初期化します。 parentCurrencyは、それ自体または他の兄弟によって初期化/更新されてもよい。 これは、メッセージの受け渡しに関する限り、あなたの親が兄弟のメディエーターとして行動する必要があることを意味します。

子供

export class EveComponent implements OnInit { 
    @Input() 
    selectedCurrency :string; 
    ngOnInit() { 
     this.selectedCurrency = localStorage.getItem("currency"); 
    } 
} 

親テンプレート

<child [selectedCurrency ]="parentCurrency"></child> 

ngOnInit() {  
    this.selectedLanguage = "EN"; 
    this.parentCurrency = "EUR"; // this property can be changed/updated and expected to be observed. 
    //also setting to local storage 
    localStorage.setItem('currency', this.parentCurrency); 
} 

A Githubのサンプルは間違いなく何が起こっているのかデバッグに役立ちます。

+0

まだ動作していません – Sajeetharan

+0

@ githubにデモを入れてあなたのケースを再現できますか?完全な話がなくても何が起こっているのかを知るのは難しいです。 – Ankesh

+0

私は実際に国際化を実装することを望んでいる、私は通貨を設定するドロップダウンがあります。ホームページに設定されている場合は、パイプを使用してすべての子コンポーネントに適用する必要があります – Sajeetharan

関連する問題