admin管理员组文章数量:1289383
I apologize in advance for code formatting. I have a data source like this:
var data = {
key1: 'value',
key2: 123,
key3: {
key30: 'value',
key31: {
key310: 123,
key311: 'hello'
}
}
}
Using React, I try to convert it into a <ul>
like this:
<ul id="data">
<li>key1: value</li>
<li>key2: 123</li>
<li>key3: [Object]
<ul>
<li>key30: value</li>
<li>key31: [Object]
<ul><li>key310: 123</li>
<li>key311: hello</li>
</ul>
</li>
</ul>
</li>
</ul>
So far, I've tried:
React.createClass({
getInitialState: function() {
return {lists: [{
key1: 'value',
key2: 123,
key3: {
key30: 'value',
key31: {
key310: 123,
key311: 'hello'
}
}
}]}
},
generateFirst: function(parent, data, tempContainer) {
var li
var liHead
var wrap
var key
for (key in data) {
if (this.getType(data[key]) === 'object') {
// li head
liHead = React.DOM.li({
className: 'token-head'
}, key + ':' + data[key])
// line
li = React.DOM.li({
className: 'iop'
}, React.DOM.ul({
className: 'iok'
}, this.generateFirst(data[key])))
// wrap
wrap = React.DOM.ul({
className: 'wrap-ul'
}, li)
tempContainer.push(liHead)
tempContainer.push(wrap)
} else {
li = React.DOM.li({
className: 'iol'
}, key + ':' + data[key])
tempContainer.push(li)
}
}
},
renderTokenContent: function(data) {
var tempContainer = []
this.generateFirst(data, tempContainer)
return (<ul>{tempContainer}</ul>)
},
render: function() {
var self = this
return (<ul className="scroll-helper">
{ this.state.lists.map(function(data) {
return (<li >
{ self.renderTokenContent(data) }
</li>)
}) }
</ul>)
}
})
It parses the whole tree but it doesn't render the elements in the right container.
I apologize in advance for code formatting. I have a data source like this:
var data = {
key1: 'value',
key2: 123,
key3: {
key30: 'value',
key31: {
key310: 123,
key311: 'hello'
}
}
}
Using React, I try to convert it into a <ul>
like this:
<ul id="data">
<li>key1: value</li>
<li>key2: 123</li>
<li>key3: [Object]
<ul>
<li>key30: value</li>
<li>key31: [Object]
<ul><li>key310: 123</li>
<li>key311: hello</li>
</ul>
</li>
</ul>
</li>
</ul>
So far, I've tried:
React.createClass({
getInitialState: function() {
return {lists: [{
key1: 'value',
key2: 123,
key3: {
key30: 'value',
key31: {
key310: 123,
key311: 'hello'
}
}
}]}
},
generateFirst: function(parent, data, tempContainer) {
var li
var liHead
var wrap
var key
for (key in data) {
if (this.getType(data[key]) === 'object') {
// li head
liHead = React.DOM.li({
className: 'token-head'
}, key + ':' + data[key])
// line
li = React.DOM.li({
className: 'iop'
}, React.DOM.ul({
className: 'iok'
}, this.generateFirst(data[key])))
// wrap
wrap = React.DOM.ul({
className: 'wrap-ul'
}, li)
tempContainer.push(liHead)
tempContainer.push(wrap)
} else {
li = React.DOM.li({
className: 'iol'
}, key + ':' + data[key])
tempContainer.push(li)
}
}
},
renderTokenContent: function(data) {
var tempContainer = []
this.generateFirst(data, tempContainer)
return (<ul>{tempContainer}</ul>)
},
render: function() {
var self = this
return (<ul className="scroll-helper">
{ this.state.lists.map(function(data) {
return (<li >
{ self.renderTokenContent(data) }
</li>)
}) }
</ul>)
}
})
It parses the whole tree but it doesn't render the elements in the right container.
Share Improve this question asked Jan 19, 2016 at 1:49 Valeriu MazareValeriu Mazare 3236 silver badges12 bronze badges2 Answers
Reset to default 8Here is an example of a nested tree from https://github./calitek/ReactPatterns React.14.Common/TreeView. Note that the nested property is children in this case.
import React from 'react';
import lodashGet from 'lodash/object/get';
let TreeRootSty = {lineHeight: '120%'}
let liSty = {listStyleType: 'none'};
let ulSty = {height: 'inherit', WebkitPaddingStart: '16px'};
let ulStyle = {height: 'inherit', WebkitPaddingStart: '16px'};
let iconSty = {marginRight: '10px', width: '16px'};
let nottogglable = {
color: '#FFF',
cursor: 'pointer',
margin: '0 0 0 .8em'
};
let togglable = {
color: '#815C7C',
cursor: 'pointer',
margin: '0'
};
let options = {};
let getTreeNode = function(child, index) {
return <li key={index} style={liSty}><JTreeViewNode node={child} iconClick={this.props.iconClick} titleClick={this.props.titleClick} /></li>;
};
class JTreeViewNode extends React.Component {
constructor(props) { super(); }
iconHandler = () => {
if (this.props.node.children && this.props.node.children.length > 0) {
this.props.iconClick(this.props.node);
} else {
this.clickHandler();
}
};
clickHandler = () => { this.props.titleClick(this.props.node); };
render() {
let titleSty = {color: '#afac87', marginTop: '2px'};
let childNodes;
let pSty = nottogglable;
if (this.props.node.children && this.props.node.children.length > 0) {
childNodes = this.props.node.children.map(getTreeNode, this);
titleSty.color = this.props.node.selected ? '#7BB53B' : '#AF90A5';
} else {
titleSty.color = this.props.node.selected ? '#b58900' : '#afac87';
}
let isClosed = true;
if (this.props.node.closed != null) isClosed = this.props.node.closed;
let branch = (
<ul id='ulStyle' style={ulStyle}>
{childNodes}
</ul>
)
if (isClosed) branch = null;
let props = this.props;
let iconType = lodashGet(props, options.typeName);
if (iconType == options.icon.sun) iconSty.background = "url('./img/sun.ico') 0/16px no-repeat !important";
else if (iconType == options.icon.leaf) iconSty.background = "url('./img/leaf.ico') 0/16px no-repeat !important";
else if (iconType == options.icon.snow) iconSty.background = "url('./img/snow.ico') 0/16px no-repeat !important";
else iconSty.background = "url('./img/sun.ico') 0/16px no-repeat !important";
return (
<div id='TreeNode'>
<div id='pSty' style={pSty} className='FlexBox'>
<div id='iconSty' onClick={this.iconHandler} style={iconSty}> </div>
<div id='titleSty' onClick={this.clickHandler} style={titleSty} >
{this.props.node.title}
</div>
</div>
{branch}
</div>
);
}
}
export default class JTreeView extends React.Component {
render() {
options = this.props.options;
let childNodes = this.props.data.map(getTreeNode, this);
return (
<div id='TreeRootSty' style={TreeRootSty}>
<ul id='ulSty' style={ulSty}>
{childNodes}
</ul>
</div>
);
}
}
I had a similar problem, here is a solution; hope it helps.
const dummyData= Immutable.fromJS(
{Id:10203040,
birdIs: "The Word",
contains:{
USER_ID: 219038012,
FirstName:"John",
LastName:"Smith",
Username:"JSmith",
PassWord:"pass",
strings:{one: "Red Phis", blue:"Blue Phis"}
},
number:1337,
lists:{
a: 1,
b: 2,
c: 3
},
closer:"closed"
})
class NestedListDisplay extends React.Component {
deepDisplay(items){
var newItems = []
for (let [key, entry] of items ){
newItems[newItems.length] = (this.checker(entry, key))
}
return newItems
}
checker(entry, liKey) {
switch (typeof entry){
case 'object':
return <ul key={liKey}> {this.deepDisplay(entry)} </ul>
case 'list':
return <ul key={liKey}> {this.deepDisplay(entry)} </ul>
case 'number':
return <li key={liKey}> {entry} </li>
case 'string':
return <li key={liKey}> {entry} </li>
}
}
render() {
return (
<div>
<h1>Nested List Display</h1>
<ul> {this.deepDisplay(dummyData)} </ul>
</div>
)
}
}
ReactDOM.render(
<NestedListDisplay />,
document.getElementById('app')
)
<script src="https://cdnjs.cloudflare./ajax/libs/immutable/3.7.2/immutable.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<body>
<div id="app"></div>
</body>
Note-- I used Immutable.js to make dummyData iterable
本文标签: javascriptReact recursively render nested elementsStack Overflow
版权声明:本文标题:javascript - React: recursively render nested elements - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741465438a2380286.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论