Angular 2是从组件还是服务订阅的? [英] Angular 2 subscribe from component or service?

查看:219
本文介绍了Angular 2是从组件还是服务订阅的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个组件HospitalComponent,试图显示医院列表.它使用HospitalService中的readAll方法(从firebase返回Observable):

I have a component HospitalComponent that tries to show a list of hospitals. It uses the readAll method from the HospitalService (that returns an Observable from firebase) :

ngOnInit() {
  this.hospitalService
    .readAll() // Make a firebase call
    .subscribe(hospitals => this.hospitals = hospitals);
}

路由/hospital已插入该组件HospitalComponent.每次到达/hospital时,Angular 2都会创建一个新的HospitalComponent,并对该hospitalService进行新的调用.

The route /hospital is plugged to this component HospitalComponent. Each time I reach /hospital, Angular 2 make a new HospitalComponent, and a new call is made to the hospitalService.

每次到达/hospital时,医院列表都会延迟显示.

Each time I reach /hospital, the hospital list is showing with delay.

从服务构造函数本身检索医院列表是否是一种好习惯?这样,我可以从后台管理刷新列表,而不会有延迟.我将在组件中:

Is it a good practice to retrieve the hospital list from the service constructor itself ? This way, I can manage the refresh list from background, instead of having some delay. I would have in the component :

ngOnInit() {
  this.hospitals = this.hospitalService.readAll();
}

以及在服务中:

constructor(private hospitalService: HospitalService) {
  hospitalService.subscribe(hospitals => this.hospitals = hospitals);
}

但这意味着要手动管理所有医院变更..

But this implies to manage manually all hospital changes ..

推荐答案

从技术角度来看,两个解决方案"几乎是相同的-因为它们基本上是做相同的事情,所以如果您只想考虑的话,这取决于您的个人喜好.您的两个解决方案.

From a technical viewpoint both "solutions" are pretty much equal - since they basically do the same thing it is up to your personal taste if you just want to conside your two solutions.

但一般来说:尝试完全避免手动订阅.

But in general: Try to avoid manual subscriptions at all.

有几处可以改进的地方(以下代码基于这样的假设:您宁愿显示一个过时的列表,该列表在后台进行更新而不是显示一个加载指示符):

There are a couple things that you can improve (the following code is based on the assumption, that you'd rather show an outdated list, that is updated in the background than to show a loading-indicator):

  • 尝试避免手动订阅(尤其是组件中的(!!))->使用async -pipe代替
  • 尝试避免使用有状态的组件(如果可能的话,甚至使用服务)->改用流
  • try to avoid manual subscriptions (especially(!!) in components) -> use the async-pipe instead
  • try to avoid stateful components (even services if possible) -> use streams instead

您的服务

export class HospitalService {
    allHospitals$: BehaviorSubject<IHospital[]> = new BehaviorSubject<IHospital[]>([]);

    // the fetchAll() method can be called in the constructor, or somewhere else in the application e.g. during startup, this depends on your application-flow, maybe some login is required ect...
    fetchAll(): Observable<IHospital[]> {
        const fetch$: Observable<IHospital[]> = ...get_stuff_from_firebase().share();
        fetch$
            .do(allHospitals => this.allHospitals$.next(allHospitals);
            .subscribe();
        return fetch$; // optional, just in case you'd want to do something with the immediate result(or error) outside the service
    }
}

您的组件(=>仅注入服务)

Your component (=> just inject the service)

constructor(private hospitalService: HospitalService) {
    // nothing to do here
}

组件的模板(=>异步管道会自动管理订阅,并自动取消订阅,因此您不必担心内存泄漏等)

The template of the component (=> the async-pipe automatically manages the subscription and unsubscribes automatically as well, so you don't have to worry about memory-leaks ect...)

<div *ngFor="let hospital of (hospitalService.allHospitals$ | async)">
    {{hospital.name}}
</div>


第四个(但要扩展得多)的解决方案是使用中央存储,例如 ngrx -使用ngrx,基本上allHospitals$的一部分将被移至集中管理的存储模块,并且您将严格划分应用程序,以便服务仅执行操作,而无需获取和处理数据,即存储除了存储和发出数据外,什么都不会做.而显示数据,组件则什么都不会做.


A fourth(but much more extended) solutions would be to use a central store like ngrx - So with ngrx basically the part of allHospitals$ would be moved to a centrally managed store-module and you would strictly divide up your application, so that a service will do nothing but fetching and processing data, the store will do nothing but storing and emitting data and a component will do nothing but displaying data.

这篇关于Angular 2是从组件还是服务订阅的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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