我正在研究将状态树的一部分转换为视图模型的ngrx选择器。举一个简单的例子,在我的状态树中,我有一个manager数组。因此,我对状态树进行了以下设置,并查看了模型-

export interface Manager {
    id: string,
    name: string
}

export interface AppState {
    managers: Manager[]
}

export interface ManagersVM {
    byId: {[key: string]: Manager},
    allIds: string[]
}

export const defaultManagersVM: ManagersVM {
    byId: {},
    allIds: []
};


然后在我的选择器中,我有:

export const selectManagersVM = createSelector(selectManagers, (data) => {
    let mgrsVM: ManagersVM = { ...defaultManagersVM };
    for(let mgr of data.managers) {
        mgrsVM.byId[mgr.id] = mgr;
        mgrsVM.allIds.push(mgr.id);
    }
})


我遇到的问题是该行:

let mgrsVM: ManagersVM = { ...defaultManagersVM };


似乎没有复制defaultManagersVMs属性。 (运行选择器后,defaultManagersVM的console.log显示它现在具有非空的byId和allIds)。我的印象是,在新定义的对象内的传播算子将创建一个副本,但这似乎是错误的。如何确保选择器中的defaultManagersVM不发生突变。

最佳答案

传播运算符does not make a deep copy of nested objects,JavaScript默认不具有此功能。一种选择是使用外部库(即Lodash,它支持深度克隆)。

另外,如果您需要其他库未涵盖的某些特定功能,则可以编写自己的递归深度克隆功能。

09-07 20:26