Note: Un des objectifs de cette approche est de faciliter l'intégration éventuelle de ngrx/store, en plus de favoriser la modification des données à l'intérieur des services, de centraliser le data à l'intérieur d'un "data store" - et rendre stateless les services - et finalement de simplifier les components en maximisant leur passivité. La version ci-dessous n'implémente pas encore le concept de data store et d'action.
MyPotatoService.ts:
export class MyPotatoService {
potatos$: BehaviorSubject<PotatoApiModel[]> = new BehaviorSubject<Potato>(null);
constructor() {
this.refreshPotatos().subscribe();
}
refreshPotatos(): Observable<void>() {
this.http.get('http://potatos.com').pipe(map(potatos => this.potato$.next(potatos)));
}
addPotato(potato: Potato): Observable<void>() {
this.http.post('http://potatos.com')
.pipe(map(() => this.refreshPotatos()));
}
}
MyListOfPotatos.html:
<app-potato *ngFor="potato of myPotatoService.potatos$ | async"></app-potato>
MyPotatoForm.html:
<form #potato="ngForm"><input [(ngModel)]="name" /></form>
<button (click)="myPotatoService.addPotato(potato>"></button>
Observed Data: Data dont un changement sur la valeur affecte soit:
- Le UI
- D'autre data qui dérive de ce data ou dont la valeur doit être rafraîchie si ce data change.
Ex: Modèles générés à partir d'autres modèles
Ex: Modèles qui changent toujours dans la base de données lorsque des modèles dont ils dérivent changent
Tout "observed data" est maintenu à l'intérieur d'un service en tant que BehaviorSubject.
Toute action faite sur du "observed data" se fait à l'intérieur d'un service. On ne modifie pas de data directement dans un component, même si le modèle peut contenir une propriété qui adresse un feature d'un component spécifique, comme expand, active, collapse. (Trade off minimal.)
On peut avoir dans un component au moins un getter si on préfère ne pas mettre le service directement dans le markup:
Exemple: get employees(): Observable<EmployeeApiModel[]> { return this.employeeService.employees$; }
Dans le html, le pipe "async" se charge de resolver le BehaviorSubject. (Lui inferrer le type "Observable" comme montré plus haut fonctionne puisqu'il l'extend.)
- Expose data as Observable
- Separate http service from store service