2017-07-07 1 views
1

私は統計アプリケーションを持っています。私のページの左側には、グループのトップリストにテーマのリストがあります。主要部分には、テーマとグループの両方に関連する統計項目が含まれています。アングルクロスサービス通信

また、私のアプリケーションにビジネスロジックを提供するいくつかのサービスがあります。説明を簡単にするために、3つについて説明しましょう:ThemeSerivce、GroupServiceおよびStatisticsService

エンドユーザーはテーマとグループのリストを操作してアイテムを追加または削除することができます。変更するたびに統計情報を再計算する必要があります。このアプリケーションでは、の科目サブスケジュールrx.jsを使用して、この種の変更を追跡します。

だから、私のコンポーネントで、私はこのような何か書くことができます:ためため

をGroupComponent

removeGroup() { 
     this.groupService.removeGroup(this.group); 
     this.statisticsService.updateStatistics(); 
     } 

ThemeComponent

removeTheme() { 
    this.themeService.removeTheme(this.theme); 
    this.statisticsService.updateStatistics(); 
    } 

しかし、論理的にこれらのコンポーネントがありません統計情報を知るもちろん、私はThemeServiceGroupServiceStatisticsServiceの依存関係を移動することができ、その後私は、テーマやグループのコレクションを変更するあらゆる方法でstatisticsService.updateStatistics()を呼び出す必要があります。だから私はサブスクリプションとの直接的なクロスサービス通信を実装したいのです。

そして最後に、私の質問:それはすべてでは良いアイデア

  1. ですか?

  2. もし問題がなければ、それを実装する最良の方法は何ですか? Iコンポーネントに購読を使用すると、私はngOnInit(に登録)方法とメモリリークを防ぐために、ngOnDestroy()に退会。 サービスのコンストラクタでそれを購読できますか?そしていつ、どこで私は退会すべきですか?あるいは、私がAppモジュールレベルでプロバイダとしてサービスを登録するときには必要ではないでしょうか?

答えて

0

StatisticsServiceは、テーマとグループのリストに登録する必要があります。個々のコンポーネントは、それぞれのサービス(ThemeService to ThemeService、Group to Groupなど)にのみ登録する必要があります。

簡略化のため、私はちょうどThemeServiceに焦点を当てますが、GroupServiceは似ています。 ThemeServiceは、削除が呼び出されたときに内部のSubjectを持つ必要があります。Subjectは次に値(おそらくは新しいリスト全体)になります。

StatisticsServiceは、変更後に観測可能であり、再計算することができます。これは次のようになります

/* theme.service.ts */ 
@Injectable() 
export class ThemeService { 
    private _list$ = new Subject<ThemeList>(); 

    get list(): Observable<ThemeList> { 
     return this._list$.asObservable(); 
    } 

    set list(newList: ThemeList) { 
     this._list$.next(newList); 
    } 
} 


/* statistics.service.ts */ 
@Injectable() 
export class StatisticsService { 
    private _calculation$ = new Subject<StatisticResult>(); 

    constructor(private themeService: ThemeService) { 
     themeService.list.subscribe((themeList: ThemeList) => this.updateCalculation(themeList)); 
    } 

    get calculation(): Observable<StatisticResult> { 
     return this._calculation$.asObservable(); 
    } 

    updateCalculation(newData: ThemeList | GroupList) { 
     // ... do stuff 
     this._calculation.next(statisticResult); 
    } 
} 


/* statistics.component.ts */ 
@Component({ 
    selector: 'statistics', 
    template: '<p>{{ statisticResult$ | async }}</p>' 
}) 
export class StatisticsComponent { 
    statisticResult$: Observable<StatisticResult>; 

    constructor(private statisticsService: StatisticsService) { 
     this.statisticResult$ = statisticsService.calculation; 
    } 
}