[英]How to use JavaScript spread... syntax to change the one field of the object, that belongs to the array and is accessed by name-value pair?
Here is the code (it fails to compile at the sentence that builds the state2, ie at the second spread):这是代码(它无法在构建 state2 的句子中编译,即在第二次传播时):
let line_id = 6;
let state = {
invoice: {
id: 1015,
description: 'web order',
},
lines: [
{id: 5, description: 'phone', color: 'black'},
{id: 6, description: 'tablet', color: 'blue'},
{id: 7, description: 'computer', color: 'gray'},
]
};
//this alert and this access pattern works, so, I would like to use
//.find... to access element in spread... structure as well
//alert(state['lines'].find(line=>line['id']==line_id)['description']);
let state2 = {
...state,
['lines']: { ...state['lines'],
find(line=>line['id']==line_id): { ...state['lines'].find(line=>line['id']==line_id),
['description']: 'TV',
},
},
};
alert(state2['lines'].find(line=>line['id']==line_id)['description']);
I have state
structure, I access lines
array, I access the specific line by name-value pair id=6
and I would like to change the value of the field description
.我有
state
结构,我访问lines
数组,我通过名称-值对id=6
访问特定行,我想更改字段description
的值。 This effort is the continuation of https://stackoverflow.com/a/64116308/1375882 in which I am trying to create the general procedure, that use the spread... syntax and the access-by-name strategy for updating the complex object/array tree.这项工作是https://stackoverflow.com/a/64116308/1375882的延续,我试图在其中创建通用程序,该程序使用扩展...语法和按名称访问策略来更新复杂对象/数组树。 In fact - this complex tree is the state of the Redux reducer and that update happend in the action that process the
valueSetter
function of the AgGrid.事实上 - 这个复杂的树是 Redux reducer 的状态,更新发生在处理
valueSetter
函数的操作中。 But - this is generally the interesting exercise by itself to better understand spread... and JavaScript and JSON structure in JavaScript.但是 - 这本身通常是一个有趣的练习,可以更好地理解传播......以及 JavaScript 中的 JavaScript 和 JSON 结构。
So - the only question is: how to write line所以 -唯一的问题是:如何写行
find(line=>line['id']==line_id): { ...state['lines'].find(line=>line['id']==line_id),
so that the code compiles?以便代码编译? How can I access the certain element of the array by name-value pair in this setting :
如何在此设置中通过名称-值对访问数组的特定元素:
Note, that I am trying to build general code :请注意,我正在尝试构建通用代码:
find(line=>line[keyFieldName]==keyFieldValue): { ...state['lines'].find(line=>line[keyFieldName]==keyFieldValue),
that uses arbitrary field names and field values - so that such handler can update the any field of the any record of arbitrary 2D AgGrid in React/Redux setting.使用任意字段名称和字段值 - 以便此类处理程序可以更新 React/Redux 设置中任意 2D AgGrid 的任何记录的任何字段。
The desired result of my code: 1) it should compile;我的代码的预期结果:1)它应该编译; 2) the second alert should return 'TV'.
2) 第二个警报应该返回“TV”。
If I understood correctly what you want to achieve, this should work:如果我正确理解了您想要实现的目标,这应该有效:
let line_id = 6; let state = { invoice: { id: 1015, description: 'web order', }, lines: [{ id: 5, description: 'phone', color: 'black' }, { id: 6, description: 'tablet', color: 'blue' }, { id: 7, description: 'computer', color: 'gray' }, ] }; const stateKeyId = 'lines'; const itemKeyId = 'id'; const itemAttr = 'description' let state2 = { ...state, [stateKeyId]: state[stateKeyId].map(item => { if (item[itemKeyId] == line_id) { return ({ ...item, [itemAttr]: 'TV' }); } return item }) } console.log(state2);
find(line=>line['id']==line_id)
should become [find(line=>line['id']==line_id)]
, since just like the string it must be between square brackets for js to work properly. find(line=>line['id']==line_id)
应该变成[find(line=>line['id']==line_id)]
,因为就像字符串一样,它必须在方括号之间才能让js工作适当地。
Also, if you are using find
from lodash
, it will return the object, therefore if you need to use the id as key you can do something like:此外,如果您使用
find
from lodash
,它将返回对象,因此如果您需要使用 id 作为键,您可以执行以下操作:
[get(find(line => line['id'] === line_id]), 'id')]: whatever
a few observations though:一些观察:
You can use the map method from arrays to return different elements based on the original one.您可以使用数组中的map方法返回基于原始元素的不同元素。
Here's how you could use it:以下是您可以如何使用它:
line_id = 6; state = { invoice: { id: 1015, description: 'web order', }, lines: [ {id: 5, description: 'phone', color: 'black'}, {id: 6, description: 'tablet', color: 'blue'}, {id: 7, description: 'computer', color: 'gray'}, ] }; state2 = { ...state, lines: state.lines.map(line => { if (line.id === line_id) return { ...line, description: 'YT' } return { ...line } }) }; alert(state2['lines'].find(line=>line['id']==line_id)['description']);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.