2016-05-31 6 views
0

У меня есть приложение с деревом вложенных узлов. все узлы одного типа.добавить новые данные внутри дерева дерева редукции

{ 
id: 1, 
title: "node_1", 
children: [ 
    { 
     id: 2, 
     title: "node_2", 
     children: [] 
    }, 
    { 
     id: 3, 
     title: "node_3", 
     children: [] 
    } 
] 

}

Когда пользователь расширил некоторый узел (например, узел с идентификатором === 3) я должен выполнить запрос в базу данных и вставить ответ (детский массив) внутри «детей» свойства узла с id === 3. Таким образом, в результате приложение состояние должно быть так:

{ 
id: 1, 
title: "node_1", 
children: [ 
    { 
     id: 2, 
     title: "node_2", 
     children: [] 
    }, 
    { 
     id: 3, 
     title: "node_3", 
     children: [ 
      { 
       id: 4, 
       title: "node_4", 
       children: [] 
      }, 
      { 
       id: 5, 
       title: "node_5", 
       children: [] 
      } 
     ] 
    } 
] 

}

как я могу вставить массив детей внутри node_3 детей собственности?

+0

я настоятельно рекомендую посмотреть на этом перевождь дерева например https://github.com/reactjs/ redux/tree/master/examples/tree-view – ctrlplusb

ответ

1

Дано:

const layer1Id = 1; 
const layer2Id = 3; 
const newArray = [ 
    { 
    id: 4, 
    title: "node_4", 
    children: [], 
    }, 
    { 
    id: 5, 
    title: "node_5", 
    children: [], 
    } 
]; 

Затем в редукторе вы будете делать:

return Object.assign({}, state, { children: state.children.map(child => { 
    if (child.id !== layer1Id) return child; 
    return Object.assign({}, child, { children: child.children.map(node => { 
    if (node.id !== layer2Id) return node; 
    return Object.assign({}, node, { children: node.children.concat(newArray) }); 
    })}); 
})}); 

Чтобы убедиться, что вы не мутировать предыдущее состояние. Если он динамически или глубоко вложен, я рекомендую вам написать некоторую рекурсивную функцию и использовать ее вместо этого.

Редактировать: здесь образец рекурсивного решения (непроверенный). indices в порядке по уровню (т.е. indices[0] относится к идентификатору первого уровня, в indices[1] относится к идентификатору второго уровня в):

const state = { ... }; 
const indices = [1, 3, 4, 5, 6]; 
const newArray = [ ... ]; 

const recursion = (node, ids, newChildren) => { 
    let children; 
    if (ids.length === 0) { 
    children = newChildren; 
    } else { 
    children = node.children.map(child => { 
     if (child.id !== ids[0]) return child; 
     return Object.assign({}, child, { children: recursion(child, ids.slice(1), newChildren) }); 
    }); 
    } 
    return Object.assign({}, node, { children }); 
}; 

recursion(state, indecies, newArray); 
+0

да, она будет глубоко вложенной. Можете ли вы присоединить некоторую ссылку к этим рекурсивным функциям, которые могут соответствовать этим обстоятельствам? –

+0

Конечно, дайте мне время. – Kujira

+0

@PavelPoberezhnyi Я добавил рекурсивное решение. – Kujira

-1

Просто перейдите к массиву children и нажмите, чтобы исправить его.

var id = expandedItemId; 
for(var i = 0; i < obj.children.length; i++){ 
    if(obj.id == expandedItemId){ 
    obj.children.push(`data got from server`); 
    } 
} 
+1

Не лучше ли возвращать новые экземпляры массивов? – ctrlplusb

+0

Извините @ctrlplusb не понял, что вы имеете в виду. Не могли бы вы прояснить? – Ashot

+2

@ctrlplusb да, это так. Так что это должно быть что-то вроде 'obj.children.concat ('data got from server')' вместо этого в выражении if. – Kujira

1

Предложенный подход для реляционных или нормированных данных в хранилище Redux является организовать его в «нормализованной» способом, аналогично с таблицами базы данных. Это упростит управление обновлениями. См. http://redux.js.org/docs/FAQ.html#organizing-state-nested-data, How to handle tree-shaped entities in Redux reducers? и https://github.com/reactjs/redux/pull/1269.

+0

спасибо, я сейчас прочту это сейчас –

Смежные вопросы