我正在laravel中执行创建动态菜单的功能,我有如下tbl_menu表:
menu_id parent_id menu_name link order
1 0 Level_1 url_1 1
2 0 Level_1 url_2 1
3 2 Level_2 url_3 2
4 2 Level_2 url_4 3
5 4 Level_3 url_5 3
我希望结果是这样的数组:
-Level_1
-Level_2
-Level_2
-Level_1
_Level_2
_Level_2
_Level_3
我的代码如下:
public function SelectAllChildeLv1ByParentId($id){
$result = DB::table('tbl_menu')->where('parent_id', $id)
->orderBy('order', 'asc')->get();
return $result;
}
public function SelectAllMenuParent(){
$result = DB::table('tbl_menu')->where('parent_id', 0)
->orderBy('order', 'asc')->get();
return $result;
}
public function getMenuChildren($listParent, $step = 3)
{
$results = [];
if ($step > 0) {
$step--;
if($listParent) {
foreach($listParent as $index => $parent) {
$listChild = $this->SelectAllChildeLv1ByParentId($parent->menu_id);
$listChild1 = $this->getMenuChildren($listChild, $step);
$results[$index] = $parent;
$results[$index]->menu_child = $listChild1;
}
}
}
return $results;
}
public function getAllMenus() {
$allMenuParent = $this->SelectAllMenuParent();
$results = $this->getMenuChildren($allMenuParent);
return $results;
}
结果是正确的,但运行的查询太多。我想优化它,但还没有弄清楚。谢谢你的帮助。
try:
public function get()
{
$menu = DB::table('tbl_menu')
->orderBy('order', 'asc')->get();
$parents = $menu->where('parent', 0);
$items = self::tree($parents, $menu);
return $items;
}
public function tree($items, $all_items)
{
$data_arr = array();
foreach ($items as $i => $item) {
$data_arr[$i] = $item->toArray(); //all column attributes
$find = $all_items->where('parent', $item->id);
//$data_arr[$i]['tree'] = array(); empty array or remove if you dont need it
if ($find->count()) {
$data_arr[$i]['tree'] = self::tree($find, $all_items);
}
}
return $data_arr;
}
使用雄辩。
首先,将其添加到"tbl_menu"模型中:
protected $with = ['children'];
public function children()
{
return $this->hasMany(YOUR_CLASS_NAME::class, 'parent_id', 'id')->orderBy('order');
}
现在如果你调用主菜单,所有的子菜单。
等等:CCD_ 1。
然后您可以在调用时使用递归
public $menus = [];
public $level = 0;
public function getMenus($request){
$menus = YOUR_CLASS_NAME::where('parent_id', 0)
->orderBy('order')
->get();
$this->recursiveMenu($menus);
return $this->menus;
}
public function recursiveMenu($menus, $lvl = 0){
foreach ($menus as $key => $menu) {
$this->menus[$menu->id] = str_repeat('—', $lvl).' '.$menu->title;
if($menu->children){
$this->level++;
$this->recursiveMenu($menu->children, $this->level);
}
if (!isset($menu[$key+1])) {
$this->level--;
}
}
}