Yii2基于Bootstrap实现三级菜单问题求助
Hey there! Let's get that third-level menu working in your Yii2 Bootstrap setup. The root issues right now are:
- Your current data-fetching methods only pull up to the second level of menus
- The view code doesn't handle rendering nested third-level items
Here's a step-by-step fix:
Step 1: Update the Menu Data Retrieval
First, replace your existing menuList() and subMenuList() methods with a function that fetches full nested menu data (supports up to 3+ levels):
public static function getNestedMenu() { // Get top-level menus (parent = 0 or NULL) $topMenu = \Yii::$app->db->createCommand(" SELECT page_id, page_name, focus_areaid, category FROM sas_pages WHERE (parent = 0 OR parent IS NULL) AND display_nav=1 AND is_publish=1 AND is_active=1 ")->queryAll(); // Add second-level menus, then third-level menus foreach ($topMenu as &$item) { // Fetch second-level children $subMenu = \Yii::$app->db->createCommand(" SELECT page_id, page_name, parent, focus_areaid, category FROM sas_pages WHERE parent = :parent AND is_publish=1 AND is_active=1 ", [':parent' => $item['page_id']])->queryAll(); // Fetch third-level children for each second-level menu foreach ($subMenu as &$subItem) { $subSubMenu = \Yii::$app->db->createCommand(" SELECT page_id, page_name, parent, focus_areaid, category FROM sas_pages WHERE parent = :parent AND is_publish=1 AND is_active=1 ", [':parent' => $subItem['page_id']])->queryAll(); $subItem['children'] = $subSubMenu; } $item['children'] = $subMenu; } return $topMenu; }
In your controller, call this method and pass the data to the view:
$menuList = YourModel::getNestedMenu(); // Replace "YourModel" with your actual model name return $this->render('your-view-file', ['menuList' => $menuList]);
Step 2: Update the View to Render Third-Level Menus
Replace your existing view code with this, which handles nested third-level items. We'll also add the necessary Bootstrap submenu styling:
First, add this CSS to your layout or view (Bootstrap doesn't support third-level menus by default):
.dropdown-submenu { position: relative; } .dropdown-submenu > .dropdown-menu { top: 0; left: 100%; margin-top: -6px; margin-left: -1px; border-radius: 0 6px 6px 6px; } .dropdown-submenu:hover > .dropdown-menu { display: block; } .dropdown-submenu > a:after { display: block; content: " "; float: right; width: 0; height: 0; border-color: transparent; border-style: solid; border-width: 5px 0 5px 5px; border-left-color: #ccc; margin-top: 5px; margin-right: -10px; } .dropdown-submenu:hover > a:after { border-left-color: #fff; }
Then update your menu HTML:
<div class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <?php foreach ($menuList as $item): ?> <?php $pageName = str_replace(' ', '-', $item['page_name']); $url = ['society/index', 'PageName' => $pageName]; $hasSubMenu = !empty($item['children']); ?> <li class="<?= $hasSubMenu ? 'dropdown' : '' ?>"> <?php if ($hasSubMenu): ?> <a href="<?= Url::to($url) ?>" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"> <?= $item['page_name'] ?> <span class="caret"></span> </a> <ul class="dropdown-menu"> <?php foreach ($item['children'] as $subItem): ?> <?php $subPageName = str_replace(' ', '-', $subItem['page_name']); $subUrl = ['society/index', 'PageName' => $subPageName]; $hasThirdLevel = !empty($subItem['children']); ?> <li class="<?= $hasThirdLevel ? 'dropdown-submenu' : '' ?>"> <?php if ($hasThirdLevel): ?> <a href="<?= Url::to($subUrl) ?>" class="dropdown-toggle" data-toggle="dropdown"> <?= $subItem['page_name'] ?> </a> <ul class="dropdown-menu"> <?php foreach ($subItem['children'] as $thirdLevelItem): ?> <?php $thirdPageName = str_replace(' ', '-', $thirdLevelItem['page_name']); ?> <li> <?= Html::a($thirdLevelItem['page_name'], ['society/index', 'PageName' => $thirdPageName]) ?> </li> <?php endforeach; ?> </ul> <?php else: ?> <?= Html::a($subItem['page_name'], $subUrl) ?> <?php endif; ?> </li> <?php endforeach; ?> </ul> <?php else: ?> <a href="<?= Url::to($url) ?>"> <?= $item['page_name'] ?> </a> <?php endif; ?> </li> <?php endforeach; ?> </ul> </div>
How This Works
- The updated
getNestedMenu()method first pulls top-level menus, then fetches their direct children (second level), and finally fetches children for each second-level menu (third level) - The view code checks for third-level items and uses Bootstrap's
dropdown-submenuclass (with custom CSS) to display them as nested dropdowns - Hovering over a second-level menu with third-level items will show the nested menu to the right
内容的提问来源于stack exchange,提问作者Chandan Kumar
相关产品推荐
相关产品推荐

