如何从数据库生成嵌套导航菜单
How to generate nested navigation menu from database
我将网站的页面存储在数据库中。使用 Laravel(尽管这对我的问题来说并不重要),我可以输出站点的层次结构并查看以下内容。 (如果需要,我可以灵活地更改数据库结构并添加更多列)
[
{
"ref_id": "1",
"parent_id": "0",
"name": "Item 1",
"child_count": 0
},
{
"ref_id": "2",
"parent_id": "0",
"name": "Item 2",
"child_count": 2
},
{
"ref_id": "3",
"parent_id": "2",
"name": "Item 2 Sub 1",
"child_count": 0
},
{
"ref_id": "4",
"parent_id": "2",
"name": "Item 2 Sub 2",
"child_count": 0
},
{
"ref_id": "5",
"parent_id": "0",
"name": "Item 3",
"child_count": 2
},
{
"ref_id": "6",
"parent_id": "5",
"name": "Item 3 Sub 1",
"child_count": 0
},
{
"ref_id": "7",
"parent_id": "5",
"name": "Item 3 Sub 2",
"child_count": 0
},
{
"ref_id": "12",
"parent_id": "0",
"name": "Item 4",
"child_count": 0
},
{
"ref_id": "13",
"parent_id": "0",
"name": "Item 5",
"child_count": 3
},
{
"ref_id": "14",
"parent_id": "13",
"name": "Item 5 Sub 1",
"child_count": 0
},
{
"ref_id": "15",
"parent_id": "13",
"name": "Item 5 Sub 2",
"child_count": 2
},
{
"ref_id": "16",
"parent_id": "15",
"name": "Item 5 Sub 2 SubSub 1",
"child_count": 0
},
{
"ref_id": "17",
"parent_id": "15",
"name": "Item 5 Sub 2 SubSub 2",
"child_count": 0
},
{
"ref_id": "18",
"parent_id": "13",
"name": "Item 5 Sub 3",
"child_count": 0
},
{
"ref_id": "19",
"parent_id": "0",
"name": "Item 6",
"child_count": 0
}
]
我需要遍历这些节点并输出如下所示的嵌套 UL 导航。 UL 可以嵌套多层,因此代码必须是动态的。
<ul>
<li>Item 1</li>
<li>Item 2
<ul>
<li>Item 2 Sub 1</li>
<li>Item 2 Sub 2</li>
</ul>
</li>
<li>Item 3
<ul>
<li>Item 3 Sub 1</li>
<li>Item 3 Sub 2</li>
</ul>
</li>
<li>Item 4</li>
<li>Item 5
<ul>
<li>Item 5 Sub 1</li>
<li>Item 5 Sub 2
<ul>
<li>Item 5 Sub 2 SubSub 1</li>
<li>Item 5 Sub 2 SubSub 2</li>
</ul>
</li>
<li>Item 5 Sub 3</li>
</ul>
</li>
<li>Item 6</li>
</ul>
到目前为止我所做的已经很接近了。这是目前最好的。这是 Laravel 的 blade 语法,但这是我所追求的逻辑,所以这也适用于原版 PHP。
<ul>
@php
$child_count = 0;
$total_children = 0;
@endphp
@foreach($q_list as $row)
@if($total_children)
@php $child_count++; @endphp
@endif
<li>{{ $row->name }}
@if($row->child_count)
@php
$total_children = $row->child_count;
$child_count = 0;
@endphp
<ul>
@elseif($total_children == $child_count && $total_children != 0)
@php
$total_children = 0;
$child_count = 0;
@endphp
</ul>
@endif
@if($total_children == $child_count || $row->child_count == 0)
</li>
@endif
@endforeach
</ul>
这导致:
<ul>
<li>Item 1</li>
<li>Item 2
<ul>
<li>Item 2 Sub 1</li>
<li>Item 2 Sub 2
</ul>
</li>
<li>Item 3
<ul>
<li>Item 3 Sub 1</li>
<li>Item 3 Sub 2
</ul>
</li>
<li>Item 4</li>
<li>Item 5
<ul>
<li>Item 5 Sub 1</li>
<li>Item 5 Sub 2
<ul>
<li>Item 5 Sub 2 SubSub 1</li>
<li>Item 5 Sub 2 SubSub 2
</ul>
</li>
<li>Item 5 Sub 3</li>
<li>Item 6</li>
</ol>
我觉得脚本很乱,但更重要的是,这里有两个问题。首先,每个嵌套 UL 的最后一项都省略了结束 </li>
。其次,每个嵌套的 <ul>
只关闭一次。如果嵌套的 <ul>
仅在第二级,但任何更高级别(如 Item 5 Sub 2 SubSub *)没有足够的关闭 <li></ul>
标签导致 Item 6 处于错误级别,那很好. (即仍然是项目 5 的子项)
任何人都可以帮助填补空白或让我知道实现此目标的更好方法。谢谢
你可以实现递归逻辑。
创建助手
function generate_tree($categories)
{
foreach ($categories as $category) {
echo '<li id="categoryId_' . $category->id . '">';
echo $category->name;
if ($category->children) {
echo '<ul>';
generate_tree($category->children);
echo '</ul>';
}
echo '</li>';
}
}
正在观看
<ul>
{!! generate_tree($categories) !!}
</ul>
我将网站的页面存储在数据库中。使用 Laravel(尽管这对我的问题来说并不重要),我可以输出站点的层次结构并查看以下内容。 (如果需要,我可以灵活地更改数据库结构并添加更多列)
[
{
"ref_id": "1",
"parent_id": "0",
"name": "Item 1",
"child_count": 0
},
{
"ref_id": "2",
"parent_id": "0",
"name": "Item 2",
"child_count": 2
},
{
"ref_id": "3",
"parent_id": "2",
"name": "Item 2 Sub 1",
"child_count": 0
},
{
"ref_id": "4",
"parent_id": "2",
"name": "Item 2 Sub 2",
"child_count": 0
},
{
"ref_id": "5",
"parent_id": "0",
"name": "Item 3",
"child_count": 2
},
{
"ref_id": "6",
"parent_id": "5",
"name": "Item 3 Sub 1",
"child_count": 0
},
{
"ref_id": "7",
"parent_id": "5",
"name": "Item 3 Sub 2",
"child_count": 0
},
{
"ref_id": "12",
"parent_id": "0",
"name": "Item 4",
"child_count": 0
},
{
"ref_id": "13",
"parent_id": "0",
"name": "Item 5",
"child_count": 3
},
{
"ref_id": "14",
"parent_id": "13",
"name": "Item 5 Sub 1",
"child_count": 0
},
{
"ref_id": "15",
"parent_id": "13",
"name": "Item 5 Sub 2",
"child_count": 2
},
{
"ref_id": "16",
"parent_id": "15",
"name": "Item 5 Sub 2 SubSub 1",
"child_count": 0
},
{
"ref_id": "17",
"parent_id": "15",
"name": "Item 5 Sub 2 SubSub 2",
"child_count": 0
},
{
"ref_id": "18",
"parent_id": "13",
"name": "Item 5 Sub 3",
"child_count": 0
},
{
"ref_id": "19",
"parent_id": "0",
"name": "Item 6",
"child_count": 0
}
]
我需要遍历这些节点并输出如下所示的嵌套 UL 导航。 UL 可以嵌套多层,因此代码必须是动态的。
<ul>
<li>Item 1</li>
<li>Item 2
<ul>
<li>Item 2 Sub 1</li>
<li>Item 2 Sub 2</li>
</ul>
</li>
<li>Item 3
<ul>
<li>Item 3 Sub 1</li>
<li>Item 3 Sub 2</li>
</ul>
</li>
<li>Item 4</li>
<li>Item 5
<ul>
<li>Item 5 Sub 1</li>
<li>Item 5 Sub 2
<ul>
<li>Item 5 Sub 2 SubSub 1</li>
<li>Item 5 Sub 2 SubSub 2</li>
</ul>
</li>
<li>Item 5 Sub 3</li>
</ul>
</li>
<li>Item 6</li>
</ul>
到目前为止我所做的已经很接近了。这是目前最好的。这是 Laravel 的 blade 语法,但这是我所追求的逻辑,所以这也适用于原版 PHP。
<ul>
@php
$child_count = 0;
$total_children = 0;
@endphp
@foreach($q_list as $row)
@if($total_children)
@php $child_count++; @endphp
@endif
<li>{{ $row->name }}
@if($row->child_count)
@php
$total_children = $row->child_count;
$child_count = 0;
@endphp
<ul>
@elseif($total_children == $child_count && $total_children != 0)
@php
$total_children = 0;
$child_count = 0;
@endphp
</ul>
@endif
@if($total_children == $child_count || $row->child_count == 0)
</li>
@endif
@endforeach
</ul>
这导致:
<ul>
<li>Item 1</li>
<li>Item 2
<ul>
<li>Item 2 Sub 1</li>
<li>Item 2 Sub 2
</ul>
</li>
<li>Item 3
<ul>
<li>Item 3 Sub 1</li>
<li>Item 3 Sub 2
</ul>
</li>
<li>Item 4</li>
<li>Item 5
<ul>
<li>Item 5 Sub 1</li>
<li>Item 5 Sub 2
<ul>
<li>Item 5 Sub 2 SubSub 1</li>
<li>Item 5 Sub 2 SubSub 2
</ul>
</li>
<li>Item 5 Sub 3</li>
<li>Item 6</li>
</ol>
我觉得脚本很乱,但更重要的是,这里有两个问题。首先,每个嵌套 UL 的最后一项都省略了结束 </li>
。其次,每个嵌套的 <ul>
只关闭一次。如果嵌套的 <ul>
仅在第二级,但任何更高级别(如 Item 5 Sub 2 SubSub *)没有足够的关闭 <li></ul>
标签导致 Item 6 处于错误级别,那很好. (即仍然是项目 5 的子项)
任何人都可以帮助填补空白或让我知道实现此目标的更好方法。谢谢
你可以实现递归逻辑。
创建助手
function generate_tree($categories)
{
foreach ($categories as $category) {
echo '<li id="categoryId_' . $category->id . '">';
echo $category->name;
if ($category->children) {
echo '<ul>';
generate_tree($category->children);
echo '</ul>';
}
echo '</li>';
}
}
正在观看
<ul>
{!! generate_tree($categories) !!}
</ul>