Angular 4如何通过服务将HTTP响应值传递给多个组件
Hey there! Let's fix this scenario where you want to fetch data once via HTTP and use that same response in your <app-featured>, <app-filter>, and <app-business> components. The key here is to cache the HTTP response in your service so multiple components can subscribe to it without triggering duplicate requests. Here's how to do it:
Step 1: Update Your Data Service to Cache the Response
Modify your data-video.service.ts to cache the fetched data using RxJS's shareReplay operator (this is the simplest approach for caching HTTP responses). This ensures that the first subscription triggers the HTTP call, and all subsequent subscriptions get the cached result.
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { map, shareReplay } from 'rxjs/operators'; @Injectable({ providedIn: 'root' // Ensures the service is a singleton (one instance across the app) }) export class DataVideoService { // Private observable to hold the cached data private cachedPosts$: Observable<any[]> | null = null; constructor(private http: HttpClient) { } getPosts(): Observable<any[]> { // Only make the HTTP call if we haven't cached the data yet if (!this.cachedPosts$) { this.cachedPosts$ = this.http.get('http://grace-controls.com/mind-grid/mind_select.php') .pipe( map(res => res.json()), // Transform the response to JSON shareReplay(1) // Cache the latest response for future subscribers ); } return this.cachedPosts$; } // Optional: Add a method to refresh the data if needed refreshPosts(): void { this.cachedPosts$ = null; // Clear the cache this.getPosts(); // Trigger a new HTTP call } }
Step 2: Update Each Component to Use the Cached Data
Now, each component can subscribe to getPosts() without worrying about duplicate requests. Let's update your components:
For featured.component.ts
import { Component, OnInit } from '@angular/core'; import { DataVideoService } from '../data-video.service'; @Component({ selector: 'app-featured', templateUrl: './featured.component.html', styleUrls: ['./featured.component.css'] }) export class FeaturedComponent implements OnInit { slides: any[] = []; constructor(private dataServices: DataVideoService) { } ngOnInit(): void { this.dataServices.getPosts().subscribe(posts => { // Your existing logic to update slides this.slides.splice(0, this.slides.length, ...posts); }); } }
For app-filter and app-business Components
Repeat a similar pattern in their .ts files:
import { Component, OnInit } from '@angular/core'; import { DataVideoService } from '../data-video.service'; @Component({ selector: 'app-filter', // Or 'app-business' templateUrl: './filter.component.html', // Or 'business.component.html' styleUrls: ['./filter.component.css'] // Or 'business.component.css' }) export class FilterComponent implements OnInit { posts: any[] = []; constructor(private dataServices: DataVideoService) { } ngOnInit(): void { this.dataServices.getPosts().subscribe(posts => { this.posts = posts; // Add your component-specific logic here }); } }
Bonus: Use the Async Pipe for Cleaner Code
To avoid manual subscription management (and prevent memory leaks), you can use Angular's async pipe directly in your templates. Here's how:
- In your component, define an observable property:
// In any of your components (featured, filter, business) posts$ = this.dataServices.getPosts();
- In your component's template:
<!-- Example for app-filter template --> <div *ngFor="let post of posts$ | async"> <!-- Render your filter content using post data --> </div>
The async pipe automatically subscribes to the observable and cleans up the subscription when the component is destroyed.
Key Notes
- Ensure your service is a singleton (using
providedIn: 'root') so all components share the same cache. - The
shareReplay(1)operator caches the most recent response. If you need to refresh the data later, call therefreshPosts()method in the service.
内容的提问来源于stack exchange,提问作者Rijo

