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

Angular兄弟组件间收据数据传递失败求助

问题分析与解决方案

核心问题

  1. Service非单例:Create组件的providers: [ReceiptdataService]会让组件实例化独立的Service实例,导致Create和Check组件使用的不是同一个Service,Subject消息无法跨组件传递。
  2. 未触发Subject发送:Create组件的inputData方法只调用了AddNewReceipt,没有触发Service的消息推送逻辑。
  3. 普通Subject的局限性:普通Subject仅能接收订阅之后发送的消息,Check组件初始化时无法获取已存在的收据数据。

分步修复

1. 修正Service为单例模式并优化消息推送

改用BehaviorSubject保存最新收据列表,确保新订阅组件能获取历史数据,同时设置全局单例:

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable({
  providedIn: 'root' // 全局单例,全应用共享同一个实例
})
export class ReceiptdataService {
  receipts = [
    {cusName:"Barka",buyDate:"2019-01-23",realDate:"2020-12-21",product:"macska",cusComment:"NEm tetszik",prodPrice:233423}
  ];

  // BehaviorSubject保存当前收据列表,初始值为已有数据
  private receiptSubject = new BehaviorSubject<any[]>(this.receipts);
  receipt$ = this.receiptSubject.asObservable();

  addNewReceipt(name:string, date:string,date2:string,item:string,comment:string,price:number){
    const newReceipt = {cusName:name ,buyDate:date,realDate:date2,product:item,cusComment:comment,prodPrice:price};
    this.receipts.push(newReceipt);
    // 推送更新后的完整列表,触发订阅组件更新
    this.receiptSubject.next([...this.receipts]); // 生成新数组确保变更检测生效
  }
}

2. 修正Create组件

移除组件内的Service提供者,确保使用全局单例:

import { ReceiptdataService } from 'src/app/receiptdata.service';
import { Router } from '@angular/router';
import { OnInit } from '@angular/core';

@Component({
  selector: 'app-create',
  templateUrl: './create.component.html',
  styleUrls: ['./create.component.css']
  // 移除 providers: [ReceiptdataService],避免创建局部Service实例
})
export class CreateComponent implements OnInit {
  cusName:string="";
  buyDate:string="";
  realDate:string="";
  product:string="";
  cusComment:string="";
  prodPrice:number=0;

  constructor(private router: Router,private receiptdataService: ReceiptdataService) { }

  ngOnInit(): void {}

  inputData(){
    this.receiptdataService.addNewReceipt(
      this.cusName, 
      this.buyDate, 
      this.realDate, 
      this.product, 
      this.cusComment, 
      this.prodPrice
    );
    // 可选:提交后清空表单
    this.cusName = "";
    this.buyDate = "";
    this.realDate = "";
    this.product = "";
    this.cusComment = "";
    this.prodPrice = 0;
  }
}

3. 修正Check组件

订阅Service的receipt$获取完整收据列表,并在组件销毁时取消订阅防止内存泄漏:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { ReceiptdataService } from 'src/app/receiptdata.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-check',
  templateUrl: './check.component.html',
  styleUrls: ['./check.component.css']
})
export class CheckComponent implements OnInit, OnDestroy {
  subscription: Subscription;
  receipts: any[] = [];

  constructor(private router: Router,private receiptdataService: ReceiptdataService) { }

  ngOnInit(): void {
    this.subscription = this.receiptdataService.receipt$.subscribe(res => {
      this.receipts = res; // 直接赋值完整列表
      console.log('当前收据列表:', res);
    });
  }

  ngOnDestroy(): void {
    // 销毁订阅,避免内存泄漏
    this.subscription.unsubscribe();
  }
}

4. Check组件HTML表格展示示例

在模板中遍历receipts数组渲染表格:

<table border="1">
  <thead>
    <tr>
      <th>客户姓名</th>
      <th>购买日期</th>
      <th>实际日期</th>
      <th>产品</th>
      <th>客户评价</th>
      <th>价格</th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let item of receipts">
      <td>{{ item.cusName }}</td>
      <td>{{ item.buyDate }}</td>
      <td>{{ item.realDate }}</td>
      <td>{{ item.product }}</td>
      <td>{{ item.cusComment }}</td>
      <td>{{ item.prodPrice }}</td>
    </tr>
  </tbody>
</table>

内容的提问来源于stack exchange,提问作者Rebeka Süveges

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:51:23