-1

我有有效载荷 A,它代表一个 n 深的嵌套树,它看起来像..(您可以将 section 数组视为树上的子项)

const data = {
  id: 123,
  sections: [{
    id: 1,
    sections:[{ id: 4, sections: [ { id: 5, sections: [] } ] }]
  }, {
    id: 2,
    sections:[]
  }, {
    id: 3,
    sections:[]
  }]
};

有效载荷 A 的标准化状态如下所示

    {
  "entities": {
    "sections": {
      "1": { "id": 1, "sections": [ 4 ] },
      "2": { "id": 2, "sections": [] }, 
      "3": { "id": 3, "sections": [] },
      "4": { "id": 4, "sections": [ 5 ] },
      "5": { "id": 5, "sections": [] }
    },
    "menu": {
      "123": { "id": 123, "sections": [ 1, 2, 3 ] }
    }
  },
  "result": 123
}

如果用户要扩展第 5 节,我会离开并从服务器加载更多的孩子。标准化后从服务器返回的有效负载 B 如下所示

{
  "entities": {
    "sections": {
      “6”: { "id": 6, "sections": [] }, 
    },
    "menu": {
      "1234”: { "id": 1234, "sections": [ 6 ] }
    }
  },
  "result": 1234
}

如何编写一个 reducer 来组合(合并/映射等)规范化有效负载 A 和规范化有效负载 B,以便新的 Redux 存储状态如下所示...

    {
  "entities": {
    "sections": {
      "1": { "id": 1, "sections": [ 4 ] },
      "2": { "id": 2, "sections": [] }, 
      "3": { "id": 3, "sections": [] },
      "4": { "id": 4, "sections": [ 5 ] },
      "5": { "id": 5, "sections": [6] },
    “6”: { "id": 6, "sections": [] }
    },
    "menu": {
      "123": { "id": 123, "sections": [ 1, 2, 3 ] }
    }
  },
  "result": 123
}
4

2 回答 2

0

这应该不难实现,在你的减速器中,我确信你正在保持以前的状态,entities.sections以下列方式从以前的状态中提取值

var newData = {...state.entities.sections,newSectionPayload}

newSectionPayload应该包含新扩展部分的数据。

我还没有尝试过,但我很确定它应该可以工作。

于 2017-04-25T15:37:59.790 回答
-1

这是我解决上述问题的减速器,它似乎可以解决问题

export const productHierarchyReducer: ActionReducer<ProductHierarchyState> = (state:any={}, action: Action) => {
   switch (action.type) {
        case ADD_PRODUCTHIERARCHY:
             const normalizedTreeNodes = normalize(action.payload, TreeNodesSchema);          
             return normalizedTreeNodes; 
         case ADD_PRODUCTHIERARCHY_CHILDREN:

                   const {targetNodeId, payload} = action.payload;
                   const normalizedChildNodes = normalize(payload, TreeNodesSchema);   

                   const expandTargetNode=dotProp.set(
                        state, 
                         `entities.children.${targetNodeId}.expanded`, 
                            expanded => true
                        );

                     const updatedWithNewChildren = dotProp.set(
                        expandTargetNode, 
                         `entities.children.${targetNodeId}.children`, 
                            children => 
                            children.concat(normalizedChildNodes.entities.nodes[normalizedChildNodes.result].children)
                        );

                     const newState=dotProp.set(updatedWithNewChildren, 
                         `entities.children`,
                           children =>  Object.assign({}, children, normalizedChildNodes.entities.children) 
                         )   

                   return newState;

        default:
            return state;
    }    
};
export const ProductHierarchyReducer = {
    productHierarchy: productHierarchyReducer
}

TreeNodesSchema 也如下所示。

const nodeKey = new schema.Entity('children')
const children = new schema.Array(nodeKey);
nodeKey.define({ children });
export const TreeNodesSchema = new schema.Entity('nodes', { children });

dotProp.set() 语法属于 dot-prop-immutable https://github.com/debitoor/dot-prop-immutable

这个更新标准化状态的资源很有用 http://redux.js.org/docs/recipes/reducers/UpdatingNormalizedData.html

于 2017-04-26T10:34:02.817 回答