【问题标题】:Push function appears to be overwriting each array element in Angular推送函数似乎正在覆盖 Angular 中的每个数组元素
【发布时间】:2019-03-19 19:50:14
【问题描述】:

我正在尝试使用以下代码将一些对话消息推送到数组:

myConversations: IConversation[] = [];
myConversationMessage: IConversationMessages = {
conversationId: 0,
messageId: 0,
messageText: ''
};
myConversationMessages: IConversationMessages[] = [];

this.conversationService.getConversations().subscribe(conversations => {
  this.myConversations = conversations;

  for (let i of this.myConversations) {
    this.myConversationMessage.conversationId = i.conversationId;       
    for (let j of i.messages) {
      this.myConversationMessage.messageId = j.messageId;
      this.myConversationMessage.messageText = j.messageText; 
      this.myConversationMessages.push(this.myConversationMessage);
    }
  }

  console.log(this.myConversationMessages);
});

我正在从 JSON 对象中检索对话和其中的消息。 不是将每条消息推送到 myConversationMessages 数组,而是在控制台中输出以下内容:

0 
conversationId: 2
messageId:2
messageText: "testing"

1
conversationId: 2
messageId:2
messageText: "testing"

2
conversationId: 2
messageId:2
messageText: "testing"

3
conversationId: 2
messageId:2
messageText: "testing"

所以最终的“对话”对象是覆盖每个数组元素。

谁能告诉我为什么我的代码会这样?提前非常感谢

附:如果可以解决我的问题,我可以上传更多代码。

【问题讨论】:

  • 另外,如果我将 console.log(j.messageId + 'j.messageText') 放在内部 For 循环中,则会打印出正确的消息详细信息。 IE。最终对象不重复,就像在上面的数组中一样

标签: arrays json angular


【解决方案1】:

这是因为 JavaScript 对象是通过引用传递的:

myConversationMessages: IConversationMessages[] = [];

this.conversationService.getConversations().subscribe(conversations => {
  this.myConversations = conversations;

  for (let i of this.myConversations) {
    this.myConversationMessage.conversationId = i.conversationId;       
    for (let j of i.messages) {
      this.myConversationMessage.messageId = j.messageId;
      this.myConversationMessage.messageText = j.messageText; 
      this.myConversationMessages.push(this.myConversationMessage); // <-= Here you are pushing a reference to the same object in every loop. In every loop you are updating the single object, and the reference in each array spot points to the same object
    }
  }

  console.log(this.myConversationMessages);
});

试试这个:

  for (let i of this.myConversations) {
    for (let j of i.messages) {
      this.myConversationMessages.push({
          conversationId: i.conversationId,
          messageId: j.messageId,
          messageText: j.messageText
      });
    }
  }

这将为每次迭代创建一个新对象

【讨论】:

  • 太好了,这行得通。感谢磨坊。唯一的事情,只是在 j.messageId 之后缺少一个分号 :)
  • 不错的收获!更新
【解决方案2】:

这是因为您将引用对象添加到数组。在您的示例中,您没有将 3 个对象添加到数组中,而是将一个对象的三个引用添加了 3 次。其中一个属性的变化会导致所有其他属性的变化。

它应该是有效的:

for (let i of this.myConversations) {
    this.myConversationMessage.conversationId = i.conversationId;       
    for (let j of i.messages) {
      let item = new IConversationMessages();
      item.messageId = j.messageId;
      item.messageText = j.messageText; 
      this.myConversationMessages.push(item);
    }
  }

【讨论】:

  • 您好,非常感谢您的帮助。但是,当我使用此代码时,let item = new IConversationMessages(); 出现以下错误:'IConversationMessages' 仅指一种类型,但在此处用作值。
  • 我认为是因为 IConversationMessages 是一个接口。在这种情况下,最好使用来自@bgraham 的示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
  • 1970-01-01
相关资源
最近更新 更多