Je suis nouveau dans Angular >
v1 et j'essaie de comprendre certains concepts (venant d'un arrière-plan React / Redux).
J'ai une API RESTful que je veux obtenir données de l'API et affichez-les dans la vue / route # 1, puis autorisez l'utilisateur à explorer et voir plus d'informations dans la vue / route # 2 (en utilisant .filter ()
pour obtenir uniquement les informations pertinentes objet).
Cependant, je trouve qu'Angular télécharge les données de l'API à chaque changement de vue / route. Comment contourner cela normalement, contourner ce problème ou y a-t-il un modèle différent que les développeurs angulaires utilisent habituellement?
// src/app/components/domain-detail/domain-detail.component.ts import { Component, OnInit, OnDestroy } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { ApiClientService } from '../../core/api-client.service'; @Component({ selector: 'app-domain-detail', templateUrl: './domain-detail.component.html', styleUrls: ['./domain-detail.component.scss'] }) export class DomainDetailComponent implements OnInit, OnDestroy { domainUuid: any; domains: any; private sub: any; constructor( private ApiClient: ApiClientService, private route: ActivatedRoute ) {} ngOnInit() { // my attempt at caching (still unfamiliar with Rxjs) this.sub = this.route.params.subscribe(params => { this.domainUuid = params.uuid; }); this.ApiClient.getDomains().subscribe(data => this.domains = data.filter(item => item.uuid === this.domainUuid)); } ngOnDestroy() { this.sub.unsubscribe(); } }
// src/app/components/domains-list/domains-list.component.ts import { Component, OnInit } from '@angular/core'; import { ApiClientService} from '../../core/api-client.service'; @Component({ selector: 'app-domains-list', templateUrl: './domains-list.component.html', styleUrls: ['./domains-list.component.scss'] }) export class DomainsListComponent implements OnInit { domains: any; constructor(private ApiClient: ApiClientService) {} ngOnInit() { this.ApiClient.getDomains().subscribe(data => this.domains = data); } }
// src/app/core/api-client.service.ts import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class ApiClientService { domains; constructor(private http: HttpClient) { } getDomains() { console.info(this.domains); if (this.domains && this.domains.length) { return this.domains; } this.domains = this.http.get<Array<any>>('http://192.168.33.11:3000/domains/list'); return this.domains; } getHostCapabilities() { return this.http.get<Array<any>>('http://192.168.33.11:3000/host/capabilities'); } }
3 Réponses :
Vous pouvez utiliser shareReplay (1)
pour partager les dernières données avec les nouveaux abonnés. Mais d'après ce que j'ai compris de votre code, vous ne souhaitez charger les domaines qu'une seule fois. Par conséquent, vous pouvez appeler la requête http sur le constructeur du service, puis partager les données avec des domaines
observables comme ceci:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import {Observable} from 'rxjs'; import {shareReplay} from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class ApiClientService { domains: Observable<Array<any>>; constructor(private http: HttpClient) { this.domains = this.http.get<Array<any>>('http://192.168.33.11:3000/domains/list'); } getDomains() { return this.domains.pipe(shareReplay(1)); } getHostCapabilities() { return this.http.get<Array<any>>('http://192.168.33.11:3000/host/capabilities'); } }
Une excellente solution lorsque vous ne voulez pas d'un magasin entier.
@MarzSocks heureux d'apprendre que cela a aidé. Btw, avec votre réponse, j'ai remarqué une faute de frappe dans la réponse: D
Stockez les données dans le stockage local du navigateur après les avoir reçues dans le premier itinéraire. Utilisez ensuite ces données de stockage local dans les itinéraires suivants. (Oui, il existe un risque de sécurité.)
Vous pouvez utiliser @ ngrx / store. C'est l'implémentation de Redux pour Angular.
D'après votre code, il semble que vous appelez this.ApiClient.getDomains () dans les deux composants mentionnés, c'est pourquoi il appelle l'API lors du changement de route.
Oui, cela je comprends mais comment aborder ceci et ne pas faire cela? À quoi ressemble ce modèle? C'est tout ce que j'ai vu documenté
Si vous souhaitez que this.domains (domaines) soit disponible sur chaque composant, vous devez utiliser un service pour partager les données entre les composants. blogs.msmvps.com/deborahk/…