修改选择器上的状态对象
Modify state objects on selector
如何 return 从商店中的平面列表派生的选择器的树列表?
在我的 nrgx 商店中,我有一个平面对象列表,使用 ngrx/selector
我将该平面列表转换为树形列表。我刚刚实现了 immer
,现在正在冻结商店(这很好),但是,选择器现在抛出 ERROR TypeError: Cannot assign to read-only property 'children' of object '[object Object]'
,因为商店被冻结了。也许我的处理方式不对。
我试过克隆数组,但只读的 属性 似乎也被克隆了。我也试过克隆子项。
// ngrx/selector
export const getAllActionScriptItems = createSelector(featureSelector, state => {
if (state.items && state.items.length > 0) {
// Tired cloning the head item.
const headItem = state.items.find(i => i.isHeader) ;
const sortedActionScripts = [SortActions(state.items, headItem.id)];
return sortedActionScripts;
}
});
function SortActions(data: IActionScript[], startingId: string, noActions: boolean = false): IActionScript {
// Clone the array
const clonedData = [...data];
// Tired cloning the top level item
const topLevelItem = { ...clonedData.find(item => item.id === startingId) };
const children = GetChildren(clonedData, topLevelItem.id);
GetChildrensChildren(clonedData, children);
topLevelItem.children = children;
return topLevelItem;
}
function GetChildren(data: IActionScript[], parentId: string) {
// return data.filter(item => item.parentId === parentId).sort((a, b) => a.eventPosition - b.eventPosition);
// Tried cloning the child items
return [...data.filter(item => item.parentId === parentId).sort((a, b) => a.eventPosition - b.eventPosition)];
}
function GetChildrensChildren(data: IActionScript[], children: IActionScript[]) {
children.forEach(child => {
// ERROR TypeError: Cannot assign to read only property 'children' of object '[object Object]
child.children = GetChildren(data, child.id);
if (child.children && child.children.length > 0) {
GetChildrensChildren(data, child.children);
}
});
}
我已经解决了,通过再次使用immer
,我在createSelector
函数中产生了一个新的状态,阅读文档后,produce
删除了read-只有属性。
The TypeScript typings automatically remove readonly modifiers from your draft types and return a value that matches your original type. - Here
export const getAllActionScriptItems = createSelector(featureSelector, state => {
if (state.items && state.items.length > 0) {
const newState = produce(state, draft => {
const headItem = draft.items.find(i => i.isHeader);
const sortedActionScripts = [SortActions(draft.items, headItem.id)];
draft.items = sortedActionScripts;
});
return newState.items.find(i => i.isHeader);
}
});
如何 return 从商店中的平面列表派生的选择器的树列表?
在我的 nrgx 商店中,我有一个平面对象列表,使用 ngrx/selector
我将该平面列表转换为树形列表。我刚刚实现了 immer
,现在正在冻结商店(这很好),但是,选择器现在抛出 ERROR TypeError: Cannot assign to read-only property 'children' of object '[object Object]'
,因为商店被冻结了。也许我的处理方式不对。
我试过克隆数组,但只读的 属性 似乎也被克隆了。我也试过克隆子项。
// ngrx/selector
export const getAllActionScriptItems = createSelector(featureSelector, state => {
if (state.items && state.items.length > 0) {
// Tired cloning the head item.
const headItem = state.items.find(i => i.isHeader) ;
const sortedActionScripts = [SortActions(state.items, headItem.id)];
return sortedActionScripts;
}
});
function SortActions(data: IActionScript[], startingId: string, noActions: boolean = false): IActionScript {
// Clone the array
const clonedData = [...data];
// Tired cloning the top level item
const topLevelItem = { ...clonedData.find(item => item.id === startingId) };
const children = GetChildren(clonedData, topLevelItem.id);
GetChildrensChildren(clonedData, children);
topLevelItem.children = children;
return topLevelItem;
}
function GetChildren(data: IActionScript[], parentId: string) {
// return data.filter(item => item.parentId === parentId).sort((a, b) => a.eventPosition - b.eventPosition);
// Tried cloning the child items
return [...data.filter(item => item.parentId === parentId).sort((a, b) => a.eventPosition - b.eventPosition)];
}
function GetChildrensChildren(data: IActionScript[], children: IActionScript[]) {
children.forEach(child => {
// ERROR TypeError: Cannot assign to read only property 'children' of object '[object Object]
child.children = GetChildren(data, child.id);
if (child.children && child.children.length > 0) {
GetChildrensChildren(data, child.children);
}
});
}
我已经解决了,通过再次使用immer
,我在createSelector
函数中产生了一个新的状态,阅读文档后,produce
删除了read-只有属性。
The TypeScript typings automatically remove readonly modifiers from your draft types and return a value that matches your original type. - Here
export const getAllActionScriptItems = createSelector(featureSelector, state => {
if (state.items && state.items.length > 0) {
const newState = produce(state, draft => {
const headItem = draft.items.find(i => i.isHeader);
const sortedActionScripts = [SortActions(draft.items, headItem.id)];
draft.items = sortedActionScripts;
});
return newState.items.find(i => i.isHeader);
}
});