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

Angular子组件@Input更新时数组push对象仅覆盖未追加问题

Angular子组件数组追加失败问题

我是Angular新手,已通过@Input装饰器将父组件的productCarted对象传递到子组件。现在希望在父组件事件触发后,将该对象追加到子组件的现有同类型对象数组中,于是使用ngOnChanges钩子监听@Input对象变化并调用push方法添加,但结果是每次仅覆盖最后一条数据,无法实现数组追加,求解决办法。

父组件代码

<div class="container-fluid">
  <div class="row">
    <div class="col-md-12">
      <app-header (selectedFeature)="selection($event)"></app-header>
    </div>
  </div>
  <div class="row">
    <div class="col-md-12">
      <app-products *ngIf="loadedFeature ==='products'" (emitProduct)="addCart($event)"></app-products>
    </div>
  </div>
  <div class="row">
    <div class="col-md-6">
      <app-cart *ngIf="loadedFeature ==='cart'" [prod]="productCarted" (emitProd)="cart($event)"></app-cart>
    </div>
  </div>
</div>

子组件代码

import { Component, Input, OnChanges} from '@angular/core';
import { products } from '../products/products.model';

@Component({
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.css']
})
export class CartComponent implements OnChanges{

  @Input() prod: products;

  products: products[] = [
    new products('LED TV', 'Good viewing experience', 450,
      "https://prod.citi.isolation/c/i/aHR0cHM6Ly9pbWFnZXMucGhpbGlwcy5jb20vaXMvaW1hZ2UvUGhpbGlwc0NvbnN1bWVyLzUwUFVUNjYwNF85OC1JTVMtZW5fU0c_JGpwZ2xhcmdlJCZ3aWQ9OTYw"),
    new products('LCD TV', 'Affordable viewing experience', 200,
      "https://prod.citi.isolation/c/i/aHR0cHM6Ly9pbWFnZXMucGhpbGlwcy5jb20vaXMvaW1hZ2UvUGhpbGlwc0NvbnN1bWVyLzUwUFVUNjYwNF85OC1JTVMtZW5fU0c_JGpwZ2xhcmdlJCZ3aWQ9OTYw")
  ];

  ngOnChanges(){
    const prod = new products(this.prod.name,this.prod.description,this.prod.price,this.prod.imagePath);
    this.products.push(prod);
  }
}

问题原因及解决办法

核心原因

  1. 组件重建导致数组重置:父组件中app-cart使用了*ngIf="loadedFeature ==='cart'",当切换到其他功能再切回购物车时,子组件会被销毁重建,products数组会重置为初始的两个元素,看起来像是“覆盖”,实际是数组被重新初始化。
  2. 对象引用未更新导致ngOnChanges不触发:如果父组件每次传递的productCarted是同一个对象引用(仅修改内部属性),ngOnChanges只会在第一次接收时触发,后续事件不会触发钩子,导致无法追加新元素。

具体解决方法

方法一:避免组件重建

将*ngIf替换为[hidden],这样组件不会被销毁,数组会保留之前的内容:

<app-cart [hidden]="loadedFeature !=='cart'" [prod]="productCarted" (emitProd)="cart($event)"></app-cart>

方法二:更新对象引用触发ngOnChanges

在父组件的addCart方法中,每次创建新的对象实例,确保引用更新:

// 父组件中的addCart方法
addCart(product: products) {
  // 解构创建新对象,更新引用
  this.productCarted = {...product};
}

方法三:父组件维护购物车数组(推荐方案)

遵循Angular单向数据流理念,由父组件维护购物车数组,子组件仅负责展示:

  1. 父组件修改:
<app-cart *ngIf="loadedFeature ==='cart'" [products]="cartProducts" (emitProd)="cart($event)"></app-cart>
// 父组件类定义
cartProducts: products[] = [];

addCart(product: products) {
  // 添加新对象到数组
  this.cartProducts.push({...product});
}
  1. 子组件修改:
import { Component, Input} from '@angular/core';
import { products } from '../products/products.model';

@Component({
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.css']
})
export class CartComponent {
  @Input() products: products[] = [];
  // 无需再使用ngOnChanges,数组更新时子组件自动感知
}

方法四:优化ngOnChanges逻辑

通过SimpleChanges参数判断prod的变化,确保仅在有效更新时添加元素:

import { Component, Input, OnChanges, SimpleChanges} from '@angular/core';
import { products } from '../products/products.model';

@Component({
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.css']
})
export class CartComponent implements OnChanges{

  @Input() prod: products;
  products: products[] = [
    new products('LED TV', 'Good viewing experience', 450,
      "https://prod.citi.isolation/c/i/aHR0cHM6Ly9pbWFnZXMucGhpbGlwcy5jb20vaXMvaW1hZ2UvUGhpbGlwc0NvbnN1bWVyLzUwUFVUNjYwNF85OC1JTVMtZW5fU0c_JGpwZ2xhcmdlJCZ3aWQ9OTYw"),
    new products('LCD TV', 'Affordable viewing experience', 200,
      "https://prod.citi.isolation/c/i/aHR0cHM6Ly9pbWFnZXMucGhpbGlwcy5jb20vaXMvaW1hZ2UvUGhpbGlwc0NvbnN1bWVyLzUwUFVUNjYwNF85OC1JTVMtZW5fU0c_JGpwZ2xhcmdlJCZ3aWQ9OTYw")
  ];

  ngOnChanges(changes: SimpleChanges) {
    if (changes['prod'] && changes['prod'].currentValue && !changes['prod'].firstChange) {
      const newProd = changes['prod'].currentValue;
      const prod = new products(newProd.name, newProd.description, newProd.price, newProd.imagePath);
      this.products.push(prod);
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:32:19