Angular 跨服务通信 [英] Angular cross-service communication

查看:22
本文介绍了Angular 跨服务通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个统计应用程序.在我页面的左侧,我有主题列表,在顶部 - 组列表.主要部分包含与主题和组相关的统计项目.

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、GroupServiceStatisticsService.

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 中的 SubjectsSubsription 来跟踪此类更改.

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 的依赖移动到 ThemeServiceGroupService 中,但是我将不得不调用 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.

最后是我的问题:

  1. 这是个好主意吗?

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆