Angular 2 subscribe from component or service?

后端 未结 1 1664
生来不讨喜
生来不讨喜 2021-02-14 20:10

Context

I have a component HospitalComponent that tries to show a list of hospitals. It uses the readAll method from the HospitalServic

相关标签:
1条回答
  • 2021-02-14 20:42

    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):

    • 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

    Your Service

    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>
    

    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.

    0 讨论(0)
提交回复
热议问题