2017-11-29 21 views
0

アングル4の親子コンポーネント間でサービスデータを共有しようとしています。動作するコードがありますが、最適なオプションがあるかどうかはわかりません。サブジェクトを作成し、観察可能なメソッドにサブスクライブすることで、parent - > child間の通信に注射可能なサービスクラスを使用しています。親子でobservableにサブスクライブすることで、同じサービスクラスを再利用しています。そうすれば、私は子供と親の両方で観察可能なものを購読しています。それは正しいアプローチですか?私は他の人が@Outputデコレータをchild - > parentの間でやりとりするように提案していますが、私のコードはsubscribeメカニズムで動作しています。メモリリークのような問題は今後発生しますか?角4コンポーネント通信 - サブスクライバとの親から子へ

親コンポーネント

constructor(private _textdataservice: TinyEditorService, private _gmapService: GmapService) { 
this.subscription = this._gmapService.getMessageC2P().subscribe((message) => { 
    this.message = message; 
    this.childCallingParent(message); 
}); 
this.subscription = this._gmapService.getStoreSearchRequest().subscribe((radius) => { 
    this.radius = radius; 
    this.retrieveNearByLocations(radius); 
}); 

}

チャイルドコンポーネント - >

constructor(private _gmapService: GmapService) { 
// subscribe to home component messages 
this.mainSubscription = this._gmapService.getMessageP2C().subscribe((addresses) => { 
    this.mainCoordinates = addresses; 
}); 

this.storeSubscription = this._gmapService.getMessageP2CStore().subscribe((addresses) => { 
    this.storeCoordinates = addresses; 
    if(this.storeCoordinates){ 
    for(let coord of this.storeCoordinates){ 
     this.addNearbyStoremarker(coord.name, coord.latitude, coord.longitude); 
    } 
    } 
}); 

}

サービス - >

export class GmapService { 
 
    private _dataurl='/assets/gmapmarkers.json'; 
 
    constructor(private _http: Http){} 
 

 
    private parentSubject = new Subject<IGmapData[]>(); 
 
    private storeSubject = new Subject<IGmapData[]>(); 
 
    private childSubject = new Subject<String>(); 
 
    private radiusSubject = new Subject<number>(); 
 

 
    sendMessageP2C(latLngArray: IGmapData[]) { 
 
    this.parentSubject.next(latLngArray); 
 
    } 
 

 
    sendMessageP2CStore(latLngArray: IGmapData[]) { 
 
    this.storeSubject.next(latLngArray); 
 
    } 
 

 
    sendMessageC2P(message: string) { 
 
    this.childSubject.next(message); 
 
    } 
 

 
    requestNearByLocations(radius: number) { 
 
    this.radiusSubject.next(radius); 
 
    } 
 

 
    clearMessage() { 
 
    this.parentSubject.next(); 
 
    this.childSubject.next(); 
 
    } 
 

 
    getMessageP2C(): Observable<IGmapData[]> { 
 
    return this.parentSubject.asObservable(); 
 
    } 
 

 
    getMessageP2CStore(): Observable<IGmapData[]> { 
 
    return this.storeSubject.asObservable(); 
 
    } 
 

 
    getMessageC2P(): Observable<string> { 
 
    return this.childSubject.asObservable(); 
 
    } 
 

 
    getStoreSearchRequest(): Observable<number> { 
 
    return this.radiusSubject.asObservable(); 
 
    } 
 

 
    getStoreMarkers(): Observable<IGmapData[]> { 
 
     return this._http.get(this._dataurl) 
 
     .map((response: Response) => <IGmapData[]> response.json()); 
 
    } 
 
}

答えて

1

親と子の間を行き来する必要がある場合は、@Input()と@Output()を使用する方がよいと言います。 あなたのコンポーネントが生き生きとしたり消えたりするにつれて、Angularがあなたのためにサブスクリプションを破壊/作成するのはその理由です。 サブジェクトが便利な場所は、親子関係のないコンポーネント間でイベントをブロードキャストする必要がある場合です。 件名の使用例はFacebookです。メッセージが受信されると、ページの複数の部分が互いに関係なくそのイベントに反応します。

ただし、ngOnDestroyを実装して科目から退学すると、解決策がきちんと整えられます。 件名のアプローチを使用するリスクは、パフォーマンス上の問題を引き起こす可能性のある数百件の件名をアプリケーションに作成することになります。

+0

thx – whizKid

+0

あなたは大歓迎です! – Mehdi

0

この回答に記載されますが、メモリリークを防ぐためにngOnDestroyライフサイクルフックでサブスクリプションをキャンセルすることができます:あなたはちょうど@outputと持つEventEmitterを使用して、この余分な複雑さを必要としない限り、[how to unsubscribe several subscriber in angular 2

はおそらくです良いアイデア。

+0

返事ありがとう..私はすでに親と子の両方でngOnDestroyを使用しています。また、私は1つの実装をオンラインで見つけられなかったので、親子間の2ウェイpub-subは良いアイデアではないという事実に同意する。 @outputデコレータを使うことができましたが、サービスクラスの1か所にコードを保存したかったのです。子供に出力デコレータを使用する必要がありますか? – whizKid

+0

@Outputプロパティは子コンポーネント内にありますが、それは子と親の間で直接的にデータを渡していて、何らかの外部サービスを経由していない場合のみです。貴重な洞察を得るために –

0

@ Input @Outputは子供の子供から渡すと遅くなり、複雑になります。

他のコンポーネントでもそのデータを使用したい場合は、ストアアプローチが優れており、柔軟性があります。

+0

店舗であなたが意味するサービスアプローチ@vineet? – whizKid

関連する問題