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

Angular 5跨组件数据共享求助:Child1数据如何在Child3展示?

Sharing Data from Child1 to Child3 in Angular 5

Hey there! Since you're working with Angular 5, let's walk through a few practical solutions to get your data from Child1 (which fetches it via a service) over to Child3. Based on your component hierarchy (Root → Child1/Child2; Child2 → Child3), here are the most straightforward approaches:

This is the cleanest approach for cross-component data sharing, especially when components aren't directly parent/child. We'll use an RxJS BehaviorSubject (perfect for Angular 5) to hold and emit the data, since it retains the latest value for new subscribers.

Step 1: Create the Shared Service

First, generate a service (using ng generate service data-sharing or manually):

// data-sharing.service.ts
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';

@Injectable()
export class DataSharingService {
  // Initialize with null or a default value
  private dataSubject = new BehaviorSubject<any>(null);
  public data$ = this.dataSubject.asObservable();

  constructor() { }

  setData(data: any): void {
    this.dataSubject.next(data);
  }
}

Don't forget to add this service to your AppModule's providers array so it's available app-wide.

Step 2: Update Child1 to Send Data

In Child1, after fetching your data from your existing service, pass it to the shared service:

// child1.component.ts
import { Component, OnInit } from '@angular/core';
import { YourDataService } from './your-data.service'; // Your existing data service
import { DataSharingService } from '../data-sharing.service';

@Component({
  selector: 'app-child1',
  templateUrl: './child1.component.html'
})
export class Child1Component implements OnInit {
  fetchedData: any;

  constructor(
    private yourDataService: YourDataService,
    private dataSharingService: DataSharingService
  ) { }

  ngOnInit(): void {
    this.yourDataService.getData().subscribe(data => {
      this.fetchedData = data;
      // Send data to the shared service
      this.dataSharingService.setData(data);
    });
  }
}

Step 3: Subscribe to Data in Child3

In Child3, subscribe to the shared service's observable to get the data. Remember to unsubscribe to avoid memory leaks (we'll use takeUntil with a destroy subject here):

// child3.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { DataSharingService } from '../../data-sharing.service';
import { Subject } from 'rxjs/Subject';
import { takeUntil } from 'rxjs/operators';

@Component({
  selector: 'app-child3',
  templateUrl: './child3.component.html'
})
export class Child3Component implements OnInit, OnDestroy {
  displayData: any;
  private destroy$ = new Subject<void>();

  constructor(private dataSharingService: DataSharingService) { }

  ngOnInit(): void {
    this.dataSharingService.data$
      .pipe(takeUntil(this.destroy$))
      .subscribe(data => {
        if (data) { // Only update if data exists
          this.displayData = data;
        }
      });
  }

  ngOnDestroy(): void {
    this.destroy$.next();
    this.destroy$.complete();
  }
}

Then in Child3's template, you can display the data like:

<!-- child3.component.html -->
<div *ngIf="displayData">
  <!-- Render your data here, e.g. -->
  <h3>Data from Child1:</h3>
  <p>{{ displayData.someProperty }}</p>
</div>

2. Input/Output Chain (For Simple Hierarchies)

If you prefer not to use a service, you can pass the data up from Child1 to Root, then down through Child2 to Child3 using @Output and @Input.

Step 1: Emit Data from Child1

// child1.component.ts
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { YourDataService } from './your-data.service';

@Component({
  selector: 'app-child1',
  templateUrl: './child1.component.html'
})
export class Child1Component implements OnInit {
  @Output() dataLoaded = new EventEmitter<any>();

  constructor(private yourDataService: YourDataService) { }

  ngOnInit(): void {
    this.yourDataService.getData().subscribe(data => {
      this.dataLoaded.emit(data);
    });
  }
}

Step 2: Receive in Root and Pass to Child2

In Root's template:

<!-- app.component.html -->
<app-child1 (dataLoaded)="handleDataLoaded($event)"></app-child1>
<app-child2 [passedData]="sharedData"></app-child2>

In Root's component:

// app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  sharedData: any;

  handleDataLoaded(data: any): void {
    this.sharedData = data;
  }
}

Step 3: Pass from Child2 to Child3

// child2.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-child2',
  templateUrl: './child2.component.html'
})
export class Child2Component {
  @Input() passedData: any;
}

In Child2's template:

<!-- child2.component.html -->
<app-child3 [finalData]="passedData"></app-child3>

Step 4: Receive and Display in Child3

// child3.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-child3',
  templateUrl: './child3.component.html'
})
export class Child3Component {
  @Input() finalData: any;
}

Then display it in Child3's template just like the service approach.

3. NgRx (For Complex State Management)

If your app is going to grow and need more state control, you could use NgRx (version 4/5 for Angular 5). This involves setting up actions, reducers, and a store to hold your data. Child1 dispatches an action to save the data, and Child3 selects it from the store. However, this is overkill for a simple data transfer—stick with the shared service unless you need full state management.


For your use case, the shared service approach is the best choice—it keeps your code clean and avoids cluttering intermediate components with data passing logic.

内容的提问来源于stack exchange,提问作者Sunil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:01:23