Angular 跨服务通信 [英] Angular cross-service communication
问题描述
我有一个统计应用程序.在我页面的左侧,我有主题列表,在顶部 - 组列表.主要部分包含与主题和组相关的统计项目.
I have a statistics application. On the left side of my page I have list of themes, on the top - list of groups. The main part contains statistics items related to both theme and group.
此外,我还有一些服务为我的应用程序提供业务逻辑.为简单起见,让我们讨论其中三个:ThemeSerivce、GroupService 和 StatisticsService.
Also I have several services which provide business logic for my application. For simplicity let's talk about three of them: ThemeSerivce, GroupService and StatisticsService.
最终用户可以操作主题和组列表(添加或删除项目),每次更改后我都必须重新计算统计信息.在这个应用程序中,我使用 rx.js 中的 Subjects 和 Subsription 来跟踪此类更改.
End users could manipulate lists of themes and groups (add or remove items) and I have to recalculate statistics after each change. In this application I use Subjects and Subsription from rx.js to track such kind of changes.
所以,在我的组件中,我可以这样写:
So, in my components I could write something like this:
对于GroupComponent
removeGroup() {
this.groupService.removeGroup(this.group);
this.statisticsService.updateStatistics();
}
对于ThemeComponent
removeTheme() {
this.themeService.removeTheme(this.theme);
this.statisticsService.updateStatistics();
}
但从逻辑上讲,这些组件不必了解统计信息.当然,我可以将 StatisticsService 的依赖移动到 ThemeService 和 GroupService 中,但是我将不得不调用 statisticsService.updateStatistics() 在每一个改变主题或组集合的方法中.这就是为什么我想通过订阅实现直接的跨服务通信.
But logically these components don't have to know about statistics. Of course I can move dependency of StatisticsService into ThemeService and GroupService, but then I will have to call statisticsService.updateStatistics() in every method which changes collection of themes or groups. That's why I want to implement direct cross-service communication with subscription.
最后是我的问题:
这是个好主意吗?
Is it a good idea at all?
如果没问题,实现它的最佳方法是什么?当我在组件中使用 Subscription 时,我在 ngOnInit() 方法中注册它并在 ngOnDestroy() 中取消订阅以防止内存泄漏.我可以在服务的构造函数中订阅它吗?我应该何时或何地取消订阅?或者当我在应用模块级别将我的服务注册为提供者时可能没有必要?
If it's ok, what is the best way to implement it? When I use Subscription in components, I register it in ngOnInit() method and unsubscribe in ngOnDestroy() to prevent memory leaks. Could I subscribe it in service's constructor? And when or where should I unsubscribe? Or maybe it's not necessary when I register my services as provider on App module level?
推荐答案
StatisticsService
应订阅主题和组列表.您的各个组件应仅订阅各自的服务(ThemeComponent 到 ThemeService、Group 到 Group 等).
StatisticsService
should subscribe to the list of themes and groups. Your individual components should only subscribe to their respective services (ThemeComponent to ThemeService, Group to Group etc).
为简单起见,我将只关注 ThemeService
,但 GroupService
是类似的.ThemeService
应该有一个内部的 Subject
当 remove 被调用时,Subject
将下一个值(可能是整个新列表).
For simplicity, I'll just focus on the ThemeService
but GroupService
is similar. ThemeService
should have an internal Subject
when remove is called, the Subject
will next a value (probably the entire new list).
StatisticsService
将订阅 ThemeService
observable 并在更改后重新计算.它看起来像这样
StatisticsService
will subscribe to the ThemeService
observable and recalculate after change. It will look something like this
/* 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;
}
}
这篇关于Angular 跨服务通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!