所以我使用ngrx来管理我的应用程序中的状态。我试图添加一个新属性(选定的班次),它应该是这样的:
state: {
shifts: {
selectedShifts: [
[employeeId]: [
[shiftId]: shift
]
]
}
}
此刻,我的州看起来像这样:
state: {
selectedShifts: {
[employeeId]: {
[shiftId]: shift
}
}
}
所以你可以看到,我的选择班次"是一个属性,而不是一个数组 - 这使得难以添加/删除/查询状态。
如何将状态组合成我想要的状态?
这是我在reducer中尝试过的:
return {
...state,
selectedShifts: {
...state.selectedShifts,
[action.payload.employeeId]: {
...state.selectedShifts[action.payload.employeeId],
[action.payload.shiftId]: action.payload[shift.shiftId]
}
}
};
现在,当我试图按照我想要的方式返回状态时,结果就是这样:
state: {
selectedShifts: {
[action.payload.employeeId]:
[0]: {[action.payload.shiftId]: { shift }}
}
}
我在这里缺少什么?当我尝试替换应该是[]的{}项时,会出现此错误:","预期
哦,是的,我希望数组的索引是特定班次的id而不是[0],[1] ......
这有可能吗? 将指数从数字改为实际转移的ID是不是一个坏主意?
答案 0 :(得分:0)
在数字索引点添加数据时,数组长度类型的行为会出现。这可能会让您使用长度连接,切片,indexOf等数组方法遇到问题。数组方法改变长度推,拼接等
var fruits = [];
fruits.push('banana', 'apple', 'peach');
console.log(fruits.length); // 3
当属性是有效的数组索引并且该索引超出数组的当前边界时,在JavaScript数组上设置属性时,引擎将相应地更新数组的length属性:
fruits[5] = 'mango';
console.log(fruits[5]); // 'mango'
console.log(Object.keys(fruits)); // ['0', '1', '2', '5']
console.log(fruits.length); // 6
从对象中选择/更新状态没有问题,它与您可能习惯的状态略有不同。使用直接hashmap {objectId:Object},如果为对象id定义了更改,则找到更新/删除所需的对象是最快的。
我知道你的问题与NGRX有关,但是读取Redux不可变模式肯定会帮助你在这里添加/更新/从状态中删除对象。 https://redux.js.org/recipes/structuring-reducers/immutable-update-patterns
一般情况下,您不希望状态中的数组(至少是大型数组)对象哈希映射要好得多。
要让所选用户的数组转换为视图,您可以执行类似的操作。请注意,这不是移位索引数组,只是userId属性下的移位数组。从原状态下面的状态。
state: {
selectedShifts: {
[employeeId]: {
[shiftId]: shift
}
}
}
const getSelectedShiftsAsArray = this.store.select( getSelectedShifts() )
.map(
userShifts => {
// get array of object ids
const userIds = Object.keys( userShifts );
const ret = {};
for( const userId of userIds ) {
const collectedShifts = [];
// convert Dictionary<Shift> into a Shift[]
// get array of shift ids
const shiftIds = Object.keys( userShifts[userId] );
// map array of shift ids into shift object array
collectedShifts = shiftIds.map( shiftId => userShifts[shiftId] );
// return value for a userId
ret[userId] = collectedShifts;
}
return ret;
});
代码完全未经测试,仅用于伪代码的一级参考。您可以轻松地将其转换为NGRX选择器。状态只是存储,你如何建模它用于组件是选择器功能和&amp;组件本身。
如果你真的需要它,你可以添加。
ret[userId].shiftIds = shiftIds;
ret[userId].shifts = collectedShifts;
但这实际上取决于你打算如何使用它们。
根据我的个人经验,我会将shift实体与selectedShifts分开,但是你如何组织你的状态完全取决于你。
state: {
shifts: {
// contains shift entities as object property map id: entity
entities: Dictionary<Shift>,
selectedShifts: [
[employeeId]: number[] // contains ids for shifts
]
}
}
现在更新/删除和添加班次只是将更新的数据设置为路径shift.entities [entityId]
另外,为employeeId选择的提升将是检查id是否已经存在并将其附加到数组中(如果它不是)。 (如果这些数组非常庞大,我也可以使用对象哈希来快速访问。<employeeId>: {shiftId:shiftId}
)。