我有一个带有对象数组的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
}
}
}
}
请帮助我修复代码,以便在不更改商店结构的情况下更新值。
答案 0 :(得分:3)
更新数组中的对象时,我将重新创建一个包含所有排除对象的数组,并追加需要更新值的最后一个对象。
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'}))
-编辑
添加了代码段并更改了逻辑,因此它不会更改列表顺序。
答案 1 :(得分:3)
您可以使用 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
答案 2 :(得分:2)
使用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
})
答案 3 :(得分:0)
这是一种无需深入研究状态对象的简单方法。
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
};
}),
这假设您在成功操作中传递了一个完整的产品对象。