2016-05-20 1 views
3

Я строю дерево узлов в React.js, используя {List, ListItem, MakeSelectable} из 'material-ui/List'. В конечном итоге я подключу данные JSON, поступающие из внутреннего вызова веб-службы. У меня нет проблем декларативно не создавая вложенного списка:material-ui dynamic nestedItems в списке из данных JSON

<List> 
... 
<ListItem 
    ... 
    nestedItems={[ 
     <ListItem 
     ... 

То, что я хочу сделать, это программно создать эту вложенную структуру из данных в формате JSON. Достаточно просто создать отдельные компоненты <ListItem> и перетащить их в массив для рендеринга, но у меня возникли проблемы с вводом вложенных элементов в структуру узлов на лету.

Лучшее, что я смог сделать до сих пор, - это работать снизу вверх, находить нижний уровень узлов JSON, подталкивая их в массив, создавая родительский компонент, назначая мой ранее созданный массив как дочерние родителя и т. д. например

var Children = [ 
    <ListItem key={1} primaryText='Child 1' /> 
    <ListItem key={2} primaryText='Child 2' /> 
] 

тогда ...

var Parents = [ 
    <ListItem key={0} primaryText='Parent 1' nestedItems={Children} /> 
] 

Это немного громоздким; есть ли более изящный способ сопоставить родителей с вложенными детьми в материал-ui <List>?

ответ

2

Представьте себе, что у нас есть объект, подобный следующему ...

RootObject = { 
    children: [ 
    { 
     children: [ 
     { 
      children: [ {...props}, {...props}] 
     }, 
     ...props, 
     ] 
    }, 
    { 
     children: [...], 
    }, 
    ... 
    { 
     children: [], 
    }, 
    ], 
    ...props, 
} 

Теперь нам нужно создать узел дерева, который будет вызывать себя рекурсивно:

const mapStructure = (nodes) => { 
    if (nodes) { 
    return nodes.map(node => (
     <ListItem 
     key={node.id} 
     primaryText={node.primaryText} 
     initiallyOpen //optional 
     nestedItems={mapStructure(node.children)} 
     /> 
    )); 
    } 
}; 

И наконец:

const DynamicNestedItems = ({ RootObject }) => { 
    return (
    <List> 
     {mapStructure(RootObject)} 
    </List> 
); 
}; 

export default DynamicNestedItems; 
1

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

Я создал основной компонент ConfigurationNav, что вы можете создать экземпляр с <ConfigurationNav nav={this.state.nav}/>:

var ConfigurationNav = React.createClass({ 
    render: function() { 
    var items = []; 
    var _this = this; 
    this.props.nav.find('> navitem').each(function(i) { 
     items.push(<ConfigurationNavItem item={this} />); 
    }); 

    return (
     <List> 
     {items} 
     </List> 
    ); 
    } 
}); 

Тогда есть подкомпонента, что создает ListItem S:

var ConfigurationNavItem = React.createClass({ 
    render: function() { 
    var nested = []; 
    for (var i=0; i<this.props.item.children.length; i++) { 
     nested.push(<ConfigurationNavItem item={this.props.item.children[i]} />); 
    } 

    return (
     <ListItem key={this.props.item.id} 
      primaryText={this.props.item.getAttribute('label')} 
      nestedItems={nested} 
      /> 
    ); 
    } 
}); 

Этот подход работает для меня, но как-то Я потерял отступ вложенных элементов, все еще работая над ним.

Лука

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