【问题标题】:I am getting the same object inside the for loop for modification in angular我在 for 循环中获取相同的对象以进行角度修改
【发布时间】:2020-07-27 22:36:21
【问题描述】:

所以我想执行一个循环,它本质上修改了迭代中元素的结构。但是,为了修改,我有一个预定义的结构对象,我已将其设置为默认对象。现在,当我遍历对象数组的每个元素(需要修改的数组)时,我将默认对象与当前元素一起发送到其他一些函数,该函数基本上返回一个修改后的对象。但是,发生的事情是我传递的默认对象在每次迭代后都会被修改。如何阻止我的默认对象被修改?

例如,我有想要修改的数据

[{
    "name": "Sample 1",
    "session_id": "sample_id_1",
    "created": "2020-04-14T06:45:05.494Z",
    "isUploaded": false,
    "username": "username1",
    "topics": [
        {
            "name": "2",
            "isUploaded": true,
            "topic_id": "2"
        },
        {
            "name": "3",
            "isUploaded": true,
            "topic_id": "3"
        }
    ]
},
{
    "name": "Sample_2",
    "session_id": "sample_id_2",
    "created": "2020-04-14T05:43:10.643Z",
    "isUploaded": false,
    "username": "username2",
    "topics": [
        {
            "name": "2",
            "isUploaded": true,
            "topic_id": "2"
        },
        {
            "name": "1",
            "isUploaded": true,
            "topic_id": "1"
        },
        {
            "name": "4",
            "isUploaded": true,
            "topic_id": "4"
        }
    ]
}]

我想使用的默认对象数组是:

[
    {
      topic_id: '1',
      topic_status: '-1',
      topic_name:
      {
        en: 'Some english text 1?',
        hi: 'some hindi text 1?'
      },
      isPlayed: false,
      status: false
    }, {
      topic_id: '2',
      topic_status: '-1',
      topic_name: {
        en: 'some english text 2?',
        hi: 'some hindi text 2?'
      },
      isPlayed: false,
      status: false
    },
    {
      topic_id: '3',
      topic_status: '-1',
      topic_name: {
        en: 'some english text 3?',
        hi: 'some hindi text 3?'
      },
      isPlayed: false,
      status: false
    },
    {
      topic_id: '4',
      topic_status: '-1',
      topic_name: {
        en: 'some english text 4?',
        hi: 'some hindi text 4?'
      },
      isPlayed: false,
      status: false
    }
  ]

现在我已经编写了这个循环,它将根据默认对象修改循环内的每个元素,如下所示:

async getServerSessionsAsLocal(serverSessions) { // serverSessions contains the sample Array of Objects described above
const newArray = [];
const defaultQuestionsForLocal = await this.userService.getUserQuestions(); // this will return the default object Array described above
if (defaultQuestionsForLocal) {
  for (let i = 0 ; i < serverSessions.length; ++i) {
    const generatedSession = this.syncService.generateSession(serverSessions[i], [...defaultQuestionsForLocal]); // this function essentially modifies the serverSession object according to the default object Array
    newArray.push(generatedSession);
  }
}
return [...newArray];

}

因此,函数 generateSession 的工作原理如下: 它在提供的 serverSession[i] 对象中查找主题键(通过循环 defaultQuestionsForLocal 数组),并将其 topic_id 与 defaultQuestionsForLocal 中的 topic_id 匹配。如果匹配,它将 defaultQuestions 元素的 topic_status 更新为 3,否则保持原样。 现在考虑到我们正在使用默认 QuestionsArray 修改索引 0 处的示例数据,生成的生成会话如下所示:

{
"name": "Sample 1",
"session_id": "sample_id_1",
"created": "2020-04-14T06:45:05.494Z",
"isUploaded": false,
"username": "username1",
"topics": [
    {
        "name": "1",
        "isUploaded": false,
        "topic_id": "1",
        "topic_status": -1
    },
    {
        "name": "2",
        "isUploaded": true,
        "topic_id": "2",
        "topic_status":3,
    },
    {
        "name": "3",
        "isUploaded": true,
        "topic_id": "3",
        "topic_status": 3,
    },
    {
        "name": "4",
        "isUploaded": false,
        "topic_id": "4",
        "topic_status": -1,
    },
]

}

现在我面临的问题是,当我将 defaultQuestionsArray 传递给 generateSession 函数时,它在内部修改了这个 defaultQuestionsArray,将其分配回会话对象的主题键并返回完整的对象。对于第一次迭代,一切似乎都很好,但是对于任何后续迭代,defaultQuestions 数组都会被修改。因此,在第二次迭代之后,defaultQuestions 数组中每个元素内的 topic_status 键将根据索引 2 处的示例对象进行修改。 因此,例如在第二次迭代之后,defaultQuestionsArray 将如下所示:

[
{
  topic_id: '1',
  topic_status: '3',
  topic_name:
  {
    en: 'Some english text 1?',
    hi: 'some hindi text 1?'
  },
  isPlayed: false,
  status: false
}, {
  topic_id: '2',
  topic_status: '3',
  topic_name: {
    en: 'some english text 2?',
    hi: 'some hindi text 2?'
  },
  isPlayed: false,
  status: false
},
{
  topic_id: '3',
  topic_status: '3',
  topic_name: {
    en: 'some english text 3?',
    hi: 'some hindi text 3?'
  },
  isPlayed: false,
  status: false
},
{
  topic_id: '4',
  topic_status: '3',
  topic_name: {
    en: 'some english text 4?',
    hi: 'some hindi text 4?'
  },
  isPlayed: false,
  status: false
}

]

请注意,第 3 个索引对象设置为 3,因为它在第一次迭代中被修改,其余的在当前迭代中被修改。由于我将此结果对象分配给提供的会话对象的主题键,因此先前修改的对象的主题键也获得相同的值。这意味着,在第二次迭代之后,newArray 看起来像:

[{
 "name": "Sample 1",
 "session_id": "sample_id_1",
 "created": "2020-04-14T06:45:05.494Z",
 "isUploaded": false,
 "username": "username1",
 "topics": [
 {
    "name": "1",
    "isUploaded": false,
    "topic_id": "1",
    "topic_status": 3
 },
 {
    "name": "2",
    "isUploaded": true,
    "topic_id": "2",
    "topic_status":3,
 },
 {
    "name": "3",
    "isUploaded": true,
    "topic_id": "3",
    "topic_status": 3,
 },
 {
    "name": "4",
    "isUploaded": false,
    "topic_id": "4",
    "topic_status": 3,
 }
]
}, {
"name": "Sample_2",
"session_id": "sample_id_2",
"created": "2020-04-14T05:43:10.643Z",
"isUploaded": false,
"username": "username2",
"topics": [
    {
        "name": "1",
        "isUploaded": true,
        "topic_id": "1",
        "topic_status": 3
    },
    {
        "name": "2",
        "isUploaded": true,
        "topic_id": "2",
        "topic_status": 3
    },
    {
        "name": "1",
        "isUploaded": true,
        "topic_id": "1",
        "topic_status": 3
    },
    {
        "name": "4",
        "isUploaded": true,
        "topic_id": "4",
        "topic_status": 3
    }
]
}]

我想要的是每次我将 defaultQuestionsArray 传递给生成会话函数,它应该始终是默认数组。关于如何纠正这个问题的任何想法?

【问题讨论】:

    标签: javascript arrays angular object scope


    【解决方案1】:

    用途:

    Object.create(originalTemplateObject);
    

    如果您在修改原始文件时遇到问题,此方法会返回对象及其属性的副本而不保留引用,参考:

    Object.create

    然后你可以修改副本,而不是修改原来的引用传递。

    一个例子:

    所以你的默认对象模板是这样的:

    {
      topic_id: '1',
      topic_status: '-1',
      topic_name:
      {
        en: 'Some english text 1?',
        hi: 'some hindi text 1?'
      },
      isPlayed: false,
      status: false
    }
    

    您应该将此模板保存在所有代码之外,因为它应该是一个全局常量:

    const objectTemplate = {
      topic_id: '',
      topic_status: '',
      topic_name:
      {
        en: '',
        hi: ''
      },
      isPlayed: false,
      status: false
    }
    

    这里我们有一个创建对象的函数,然后使用传递的参数返回新对象。

    const objectTemplate = {
      topic_id: '',
      topic_status: '',
      topic_name:
      {
        en: '',
        hi: ''
      },
      isPlayed: false,
      status: false
    }
    
    const myObjects = [];
    
    function copyObject(...objectValues){
    
        let i = 0;
        const newObject = Object.create(objectTemplate);
        
        for(let prop in newObject){
           newObject[prop] = objectValues[i];
           i++;
        }
    
        return newObject;
    }
    
    myObjects.push(
      copyObject('1', '-1', {en: 'Some english text 1?',hi: 'some hindi text 1?'}, false, false
    ));
    
    console.log("array with the object copy: " + "\n");
    console.log(myObjects);
    console.log("\n" + "original object: " + "\n");
    console.log(objectTemplate);

    这是一个如何在不修改原始对象的情况下使用此方法的示例。

    【讨论】:

    • 感谢@Riven 提出答案。我也可以通过使用扩展运算符来解决这个问题。毫无疑问,Object.create 也可以在这里工作。
    猜你喜欢
    • 2018-08-10
    • 2019-08-23
    • 2012-12-01
    • 1970-01-01
    • 2021-03-25
    • 1970-01-01
    • 2023-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多