![](/img/trans.png)
[英]How to implement build in function .eval() with recursive function
[英]How to build a recursive function
關於遞歸函數有一些問題,我無法理解,想知道是否可以得到一些幫助。
我有一個像下面這樣的json對象
const data = {
"navItems": [
{
"type": "directory",
"name": "Nav Title 1",
"children": [
{
"downloadUrl": "",
"content": "",
"type": "file",
"name": "File 1.pdf"
},
{
"downloadUrl": "",
"content": "",
"type": "file",
"name": "File 2.pdf"
},
{
"type": "directory",
"name": "Sub Title 1",
"children": [
{
"downloadUrl": "",
"content": "",
"type": "file",
"name": "Sub File 1.pdf"
},
{
"downloadUrl": "",
"content": "",
"type": "file",
"name": "Sub File 2.docx"
}
]
},
{
"type": "directory",
"name": "Sub Title 2",
"children": [
{
"type": "directory",
"name": "Sub Sub Title 1",
"children": [
{
"downloadUrl": "",
"content": "",
"type": "file",
"name": "Sub Sub File 1.pdf"
},
{
"downloadUrl": "",
"content": "",
"type": "file",
"name": "Sub Sub File 2.pdf"
}
]
},
{
"type": "directory",
"name": "Sub Sub Title 2",
"children": [
{
"downloadUrl": "",
"content": "",
"type": "file",
"name": "Sub Sub File 1.pdf"
},
{
"downloadUrl": "",
"content": "",
"type": "file",
"name": "Sub Sub File 2.pdf"
}
]
}
]
}
]
}
]
}
我需要動態創建一個導航菜單,以像這樣的方式對這個數據集做出反應
let newNavItem = {
id: 'apps.' + id,
title: item.name,
type: 'collapse',
icon: 'heroicons-outline:folder',
children: [
{
id: 'paper.' + sub2item.name,
title: sub2item.name,
type: 'item',
url: sub2item.downloadUrl,
}
]
}
可折疊導航項的示例(類型 = 目錄)
{
id: id,
title: title,
type: 'collapse',
icon: 'heroicons-outline:folder',
children: []
}
將進入 children 數組的可點擊 URL 示例:(type = File)
{
id: id,
title: name,
type: 'item',
url: url,
}
編輯:這是我目前使用該功能的地方。
const buildNavBlock = (navItem) => {
if (navItem.hasOwnProperty("children") && navItem.children.length > 0 && navItem.type == "directory") {
console.log(navItem.children);
return {
id: 'apps.' + navItem.name,
title: navItem.name,
type: 'collapse',
icon: 'heroicons-outline:folder',
children: buildNavBlock(navItem.children)
}
} else {
return {
id: 'paper.' + navItem.name,
title: navItem.name,
type: 'item',
url: 'apps/documents/',
}
}
};
data.navItems.forEach((item => {
let nav = buildNavBlock(item);
console.log(nav);
}))
似乎當您調用遞歸函數時,您並沒有為每個孩子調用它。 將其更改為此可能會有所幫助:
const buildNavBlock = (navItem) => {
if (navItem.hasOwnProperty("children") && navItem.children.length > 0 && navItem.type == "directory") {
console.log(navItem.children);
return {
id: 'apps.' + navItem.name,
title: navItem.name,
type: 'collapse',
icon: 'heroicons-outline:folder',
children: navItem.children.map(child => buildNavBlock(child))
}
} else {
return {
id: 'paper.' + navItem.name,
title: navItem.name,
type: 'item',
url: 'apps/documents/',
}
}
};
data.navItems.forEach((item => {
let nav = buildNavBlock(item);
console.log(nav);
}))
這可能會有所幫助
const data = { "navItems": [ { "type": "directory", "name": "Nav Title 1", "children": [ { "downloadUrl": "", "content": "", "type": "file", "name": "File 1.pdf" }, { "downloadUrl": "", "content": "", "type": "file", "name": "File 2.pdf" }, { "type": "directory", "name": "Sub Title 1", "children": [ { "downloadUrl": "", "content": "", "type": "file", "name": "Sub File 1.pdf" }, { "downloadUrl": "", "content": "", "type": "file", "name": "Sub File 2.docx" } ] }, { "type": "directory", "name": "Sub Title 2", "children": [ { "type": "directory", "name": "Sub Sub Title 1", "children": [ { "downloadUrl": "", "content": "", "type": "file", "name": "Sub Sub File 1.pdf" }, { "downloadUrl": "", "content": "", "type": "file", "name": "Sub Sub File 2.pdf" } ] }, { "type": "directory", "name": "Sub Sub Title 2", "children": [ { "downloadUrl": "", "content": "", "type": "file", "name": "Sub Sub File 1.pdf" }, { "downloadUrl": "", "content": "", "type": "file", "name": "Sub Sub File 2.pdf" } ] } ] } ] } ] } /*let newNavItem = { id: 'apps.' + id, title: item.name, type: 'collapse', icon: 'heroicons-outline:folder', children: [ { id: 'paper.' + sub2item.name, title: sub2item.name, type: 'item', url: sub2item.downloadUrl, } ] }*/ const {useEffect, useState} = React const Dir=({data, isActive=true, collapsed=true})=>{ const [active,setActive]=useState(!collapsed) return <li className={"dir "+(isActive ? "active":"nested")} href=""> {data.title} <span className={"caret "+(active?"caret-down":"")} onClick={()=>setActive(v=>!v)}/> <ul> {(data.children || []).map(v=>v.type==="collapse"? <Dir key={v.id} data={v} isActive={active}/>:<File key={v.id} data={v} isActive={active}/>)} </ul> </li> } const File=({data,isActive})=>{ return <li className={"file "+(isActive ? "active":"nested")} href={data.url}> {data.title}</li> } const App=(props)=>{ const makeNav=(data)=> (data.type === "directory")? { id: 'paper.' + data.name, title: data.name, type: 'collapse', icon: 'heroicons-outline:folder', children: (data.children||[]).map(v=>makeNav(v)) }:(data.type === "file")? { id: 'paper.' + data.name, title: data.name, type: 'item', url: data.downloadUrl, }:"" const [nav, setNav]=useState([]) useEffect(()=>{ let v=props.data.navItems.map(v=>makeNav(v)) setNav(v) //console.log(v) },[]) return <div class="sidebar"> <ul> {nav.map(v=>v.type==="collapse"? <Dir key={v.id} data={v}/>:<File key={v.id} data={v}/>)} </ul> </div> } ReactDOM.render(<App data={data}/>,document.getElementById('app'))
/* Style sidebar links */ .sidebar li { padding: 6px 8px 6px 16px; text-decoration: none; font-size: 20px; color: #818181; } /* Style links on mouse-over */ .sidebar li:hover { color: #f1f1f1; } .caret { cursor: pointer; user-select: none; /* Prevent text selection */ } /* Create the caret/arrow with a unicode, and style it */ .caret::before { content: "\25B6"; color: black; display: inline-block; margin-right: 6px; } /* Rotate the caret/arrow icon when clicked on (using JavaScript) */ .caret-down::before { transform: rotate(90deg); } /* Hide the nested list */ .nested { display: none; } /* Show the nested list when the user clicks on the caret/arrow (with JavaScript) */ .active { display: block; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script> <div id="app"> </div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.