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

Angular创建新数组条目时所有已有对象同步变更问题

问题现象

通过HTML表单创建新条目时,新条目可正常展示,但每次创建新条目后,之前已创建的条目内容会同步发生变更。如果启用注释中的index去重判断逻辑,仅能成功创建1个对象,无法继续创建后续条目。
相关代码如下:

position.ts

export interface Position{
    index:number;
    lat: number;
    lng: number;
    time: string;
}

positions.component.ts

import { Component, OnInit } from '@angular/core';
import { Positions } from '../mock-positions';

@Component({
  selector: 'app-positions',
  templateUrl: './positions.component.html',
  styleUrls: ['./positions.component.css']
})
export class PositionsComponent implements OnInit {
  constructor() { }
  positionEntrys = 'Positions ';
  positions= Positions;
  ngOnInit(): void {
  }
}

create-poistion.component.ts

import { Component, OnInit } from '@angular/core';
import { Position } from '../position';
import { Positions } from '../mock-positions';

@Component({
  selector: 'app-create-position',
  templateUrl: './create-position.component.html',
  styleUrls: ['./create-position.component.css']
})
export class CreatePositionComponent implements OnInit {
  constructor() { }

  position: Position={
    index: Positions.length,
    lat: -1,
    lng: -1,
    time: "testdata",
  }

  ngOnInit(): void {
  }

  save() : void{
    Positions.push(this.position)
    
   //var postionByTimestamp= Positions.find(x => x.index ==this.position.index);
    //if(postionByTimestamp==null || postionByTimestamp==undefined){
      //Positions.push(this.position)
    //}
    //else{
      //postionByTimestamp=this.position
    //}
  }
}
原因分析

两个核心问题导致异常:

  • 对象引用复用:组件属性position是组件初始化时创建的单个对象,每次调用save()往数组push的都是同一个对象的引用,没有生成新对象。后续表单修改this.position的属性值时,数组中所有已存入的条目因为指向同一块内存地址,内容会同步被修改,表现为旧条目跟着新条目一起变。
  • index只初始化一次:position.index仅在组件初始化时赋值为当时的Positions.length,后续新增条目时不会重新计算。启用去重逻辑后,第一次保存后数组中已存在对应index的条目,后续每次保存查找都能匹配到重复index,不会执行push逻辑,自然只能创建1个条目。

另外注释中的更新逻辑存在错误:postionByTimestamp是find返回的局部变量,直接给该变量赋值不会修改原数组中的对象,仅会改变局部变量的指向。

修复方法

修改create-poistion.component.ts中的save方法,每次保存时创建全新的Position对象,实时计算新条目的index,保存完成后重置表单绑定的对象即可:

save() : void{
  // 每次保存生成全新对象,切断引用关联
  const newPosition: Position = {
    index: Positions.length, // 每次保存时实时取最新数组长度作为index
    lat: this.position.lat,
    lng: this.position.lng,
    time: this.position.time
  }
  Positions.push(newPosition)

  // 保存后重置表单对象,方便下一次录入
  this.position = {
    index: Positions.length,
    lat: -1,
    lng: -1,
    time: "testdata",
  }
}

如果需要保留index去重判断逻辑,注意要在计算完新index后执行判断,更新已有条目时直接修改对象属性,不要给局部变量重新赋值:

save() : void{
  const targetIndex = Positions.length;
  const existItem = Positions.find(x => x.index === targetIndex);
  const newPosition: Position = {
    index: targetIndex,
    lat: this.position.lat,
    lng: this.position.lng,
    time: this.position.time
  }

  if (!existItem) {
    Positions.push(newPosition)
  } else {
    // 直接修改原对象属性,不要给局部变量赋值
    existItem.lat = newPosition.lat;
    existItem.lng = newPosition.lng;
    existItem.time = newPosition.time;
  }

  // 重置表单
  this.position = {
    index: Positions.length,
    lat: -1,
    lng: -1,
    time: "testdata",
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:27:23