javascript - Observable vs Subject și asObservable
Învăț RxJs, caut confirmare sau corectare asupra presupunerii mele.
Încerc să creez un observable public doar pentru citire într-un serviciu pe care să pot folosi .next() în diverse locuri din clasa mea de serviciu. Mă întreb dacă aceasta este modalitatea corectă de a o face:
private myObservable = new Subject<T>();
public myObservable$: Observable<T> = this.myObservable.asObservable();
- Utilizatorul se poate abona la
myObservable$ - Pot să folosesc
myObservable.next(...);
Funcționează perfect, dar am suficientă experiență pentru a ști că s-ar putea doar să fiu un idiot fără să-mi dau seama (RxJS este imens). Este acesta un model corect și obiectul corect pentru cazul de utilizare menționat?
Răspuns #1
Ceea ce faci este corect. Există totuși o notație puțin mai scurtă. Deoarece Subject este deja un Observable (moștenește clasa Observable), poți lăsa verificarea tipului pe seama TypeScript:
private myObservable = new Subject<T>();
public myObservable$: Observable<T> = this.myObservable;
Orice consumator al serviciului tău se poate abona la myObservable$, dar nu va putea să apeleze myObservable$.next() deoarece TypeScript nu îți va permite să faci asta (clasa Observable nu are nicio metodă next()).
Aceasta este, de fapt, modalitatea recomandată de a face acest lucru, iar RxJS intern nu folosește niciodată asObservable. Pentru o discuție mai detaliată, vezi:
https://github.com/ReactiveX/rxjs/pull/2408
https://github.com/ReactiveX/rxjs/issues/2391
Vezi o întrebare foarte similară: Ar trebui ca subiectele rxjs să fie publice în clasă?
Răspuns #2
În proiect folosim acest tip de Observables, acesta oferă o încapsulare corespunzătoare pentru observable-ul tău privat, dar tot poți apela next() folosind o metodă publică.
private sourceName = new Subject<T>();
name = this.sourceProductName.asObservable();
sendName(item: T) {
this.sourceName.next(item);
}
