You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 6组件间共享HTTP GET加载数据的问题求助

How to Share a Client Object Array Between Two Angular 6 Components Using a Service

Hey there! The issue here is that your current ClientDataService uses a plain variable to store the client array, which doesn't support reactive updates. Since your client data is loaded asynchronously (via the subscription in ClientSearchComponent), by the time ClientListComponent initializes, the data might not be ready yet — and even if it loads later, the component has no way to know it changed.

Let's fix this using BehaviorSubject (which you mentioned you saw examples of, but with strings instead of arrays — it works exactly the same for arrays!). Here's how to adjust your code step by step:

1. Update the ClientDataService to use BehaviorSubject

We'll use a BehaviorSubject to hold the client array state, and expose an observable so components can subscribe to changes. This ensures any component that subscribes gets the latest value immediately, even if they load after the data is set.

import {Injectable} from '@angular/core';
import {Client} from '../models/client';
import {BehaviorSubject, Observable} from 'rxjs';

@Injectable()
export class ClientDataService {
  // Initialize with an empty array as the default value
  private clientSubject = new BehaviorSubject<Client[]>([]);
  // Expose an observable so components can subscribe (don't expose the subject directly!)
  public client$: Observable<Client[]> = this.clientSubject.asObservable();

  setData(clients: Client[]) {
    // Send the new array to all subscribers
    this.clientSubject.next(clients);
  }
}

2. Adjust ClientSearchComponent (small best practice tweak)

Your existing data fetch logic is fine — we just move the subscription to ngOnInit (a better practice than putting it in the constructor) and keep calling setData as before, which now triggers the subject to emit the new array:

import {Component, OnInit} from '@angular/core';
import {Client} from '../models/client';
import {ClientSearchService} from './client-search.service';
import {ClientDataService} from '../services/client-data.service';

@Component({
  selector: 'app-client-search',
  templateUrl: './client-search.component.html',
  styleUrls: ['./client-search.component.css']
})
export class ClientSearchComponent implements OnInit {
  public clientList: Client[];

  constructor(
    private clientSearchService: ClientSearchService, 
    private clientDataService: ClientDataService
  ) {}

  ngOnInit() {
    this.clientSearchService.list('assets/test.json').subscribe((clients: Client[]) => {
      this.clientList = clients;
      this.clientDataService.setData(clients);
    });
  }
}

3. Update ClientListComponent to subscribe to the observable

Instead of trying to get the data immediately in the constructor, we'll subscribe to the client$ observable from the service. This way, whenever the data changes (including when it's first loaded), the component will receive the latest array and update the view:

import {Component, OnInit, OnDestroy} from '@angular/core';
import {Client} from '../models/client';
import {ClientDataService} from '../services/client-data.service';
import {Subscription} from 'rxjs';

@Component({
  selector: 'app-client-list',
  templateUrl: './client-list.component.html',
  styleUrls: ['./client-list.component.css']
})
export class ClientListComponent implements OnInit, OnDestroy {
  public clientList: Client[];
  private clientSubscription: Subscription;

  constructor(private clientDataService: ClientDataService) {}

  ngOnInit() {
    // Subscribe to the client observable to receive updates
    this.clientSubscription = this.clientDataService.client$.subscribe(clients => {
      this.clientList = clients;
      console.log('Updated client list:', clients);
    });
  }

  ngOnDestroy() {
    // Always unsubscribe to prevent memory leaks!
    if (this.clientSubscription) {
      this.clientSubscription.unsubscribe();
    }
  }
}

4. Optional: Use the async pipe in your template (even cleaner!)

Instead of managing subscriptions manually, you can use Angular's async pipe in your ClientListComponent template. This automatically handles subscribing and unsubscribing, so you don't need the OnDestroy logic:

In the component:

// Remove the clientSubscription and OnDestroy implementation
public client$ = this.clientDataService.client$;

In your client-list.component.html:

<table>
  <tr *ngFor="let client of client$ | async">
    <!-- Replace with your actual client properties -->
    <td>{{client.id}}</td>
    <td>{{client.name}}</td>
  </tr>
</table>

Why this works:

  • BehaviorSubject stores the current value of the client array, so any new subscriber gets the latest value right away.
  • When ClientSearchComponent loads the data and calls setData, the subject emits the new array, triggering all subscribers (like ClientListComponent) to update.
  • Using observables ensures your components react to data changes automatically, which aligns with Angular's reactive programming model.

内容的提问来源于stack exchange,提问作者Daniel Częstki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:07:06