ngrx 更新数组内的对象
ngrx update object inside array
我有一个包含对象数组的 ngrx 存储。我正在寻找的是,使用数组索引更新(修改)数组内的对象。
我的 ngrx 数据看起来像,
policies: {
beneficiaries: {
beneficiaries: [{
name: 'pqr'
age: 56
},
{
name: 'xyz'
age: 76
}
]
}
}
我必须根据数组索引更新收款人姓名。
所以我实现了以下reducer函数
on(policiesActions.updateBeneficiaryPercentage, (state, action) => {
return {
...state,
beneficiaries: {
...state.beneficiaries,
beneficiaries: {
...state.beneficiaries.beneficiaries,
[action.index]: {
...state.beneficiaries.beneficiaries[action.index],
name: action.value
}
}
}
};
})
上面代码的问题在于
在 运行 这段代码之后,我商店的结构正在更改为
policies: {
beneficiaries: {
beneficiaries: {
0: {
name: 'pqr'
age: 1000
},
1: {
name: 'xyz'
age: 76
}
}
}
}
请帮我修正代码,这样我就可以在不改变存储结构的情况下更新值。
更新数组中的对象时,我会重新创建一个包含所有排除对象的数组,并附加需要更新值的最后一个对象。
const policies = {
beneficiaries: {
beneficiaries: [{
name: 'pqr',
age: 56
},
{
name: 'xyz',
age: 76
}
]
}
}
const updateObject = (state, action) => {
if(!state.beneficiaries.beneficiaries[action.index]) {
return state;
}
return {
...state,
beneficiaries: {
...state.beneficiaries,
beneficiaries: [
...state.beneficiaries.beneficiaries.slice(0, action.index),
{
...state.beneficiaries.beneficiaries[action.index],
name: action.value
},
...state.beneficiaries.beneficiaries.slice(action.index + 1)
]
}
};
}
console.log(updateObject(policies, {index: 1, value: 'test'}))
--编辑
添加了代码片段并更改了逻辑,因此它不会更改列表顺序。
使用Array.map
方法:
arr.map((value, index) => index === action.index ? {...value, name: action.value} : value)
或者只使用 ngrx-etc,它可以让你以可变的方式改变你的状态,同时保持不变
mutableOn(onAction, (state, action) => {
state.arr[action.index].name = action.name
return state
})
您可以使用 immer.js 生成新状态,而无需触及之前的状态。无需推出自己的解决方案,再加上通过手动克隆前一个对象来重新创建对象 容易出错。
import produce from "immer"
on(policiesActions.updateBeneficiaryPercentage, (state, action) => {
return produce(state, draftState => {
draftState.policies.beneficiaries.beneficiaries[action.index].name = action.value
})
})
如果你想以实用的方式做到这一点,你可以尝试镜头 example using ramda
这是一种简单的方法,无需深入研究状态对象。
on(ProductActions.updateProductSuccess, (state, action): ProductState => {
// define a constant and map over the existing state, inserting your new item,
// then assign your new object as the new state.
const updatedProducts = state.products.map(
product => action.product.id === product.id ? action.product : product);
return {
...state,
products: updatedProducts
};
}),
这假设您在成功操作中传递了一个完整的产品对象。
我有一个包含对象数组的 ngrx 存储。我正在寻找的是,使用数组索引更新(修改)数组内的对象。 我的 ngrx 数据看起来像,
policies: {
beneficiaries: {
beneficiaries: [{
name: 'pqr'
age: 56
},
{
name: 'xyz'
age: 76
}
]
}
}
我必须根据数组索引更新收款人姓名。 所以我实现了以下reducer函数
on(policiesActions.updateBeneficiaryPercentage, (state, action) => {
return {
...state,
beneficiaries: {
...state.beneficiaries,
beneficiaries: {
...state.beneficiaries.beneficiaries,
[action.index]: {
...state.beneficiaries.beneficiaries[action.index],
name: action.value
}
}
}
};
})
上面代码的问题在于 在 运行 这段代码之后,我商店的结构正在更改为
policies: {
beneficiaries: {
beneficiaries: {
0: {
name: 'pqr'
age: 1000
},
1: {
name: 'xyz'
age: 76
}
}
}
}
请帮我修正代码,这样我就可以在不改变存储结构的情况下更新值。
更新数组中的对象时,我会重新创建一个包含所有排除对象的数组,并附加需要更新值的最后一个对象。
const policies = {
beneficiaries: {
beneficiaries: [{
name: 'pqr',
age: 56
},
{
name: 'xyz',
age: 76
}
]
}
}
const updateObject = (state, action) => {
if(!state.beneficiaries.beneficiaries[action.index]) {
return state;
}
return {
...state,
beneficiaries: {
...state.beneficiaries,
beneficiaries: [
...state.beneficiaries.beneficiaries.slice(0, action.index),
{
...state.beneficiaries.beneficiaries[action.index],
name: action.value
},
...state.beneficiaries.beneficiaries.slice(action.index + 1)
]
}
};
}
console.log(updateObject(policies, {index: 1, value: 'test'}))
--编辑
添加了代码片段并更改了逻辑,因此它不会更改列表顺序。
使用Array.map
方法:
arr.map((value, index) => index === action.index ? {...value, name: action.value} : value)
或者只使用 ngrx-etc,它可以让你以可变的方式改变你的状态,同时保持不变
mutableOn(onAction, (state, action) => {
state.arr[action.index].name = action.name
return state
})
您可以使用 immer.js 生成新状态,而无需触及之前的状态。无需推出自己的解决方案,再加上通过手动克隆前一个对象来重新创建对象 容易出错。
import produce from "immer"
on(policiesActions.updateBeneficiaryPercentage, (state, action) => {
return produce(state, draftState => {
draftState.policies.beneficiaries.beneficiaries[action.index].name = action.value
})
})
如果你想以实用的方式做到这一点,你可以尝试镜头 example using ramda
这是一种简单的方法,无需深入研究状态对象。
on(ProductActions.updateProductSuccess, (state, action): ProductState => {
// define a constant and map over the existing state, inserting your new item,
// then assign your new object as the new state.
const updatedProducts = state.products.map(
product => action.product.id === product.id ? action.product : product);
return {
...state,
products: updatedProducts
};
}),
这假设您在成功操作中传递了一个完整的产品对象。