其實之前也寫過類似的內容,不過那是使用 jQuery EasyUI 的元件,在臺灣使用 jQuery EasyUI 的人實在是少數,不過不管是不是有沒有使用 jQuery EasyUI,重點是在於如何處理樹狀結構資料以及前端如何應用遞回的觀念將樹狀選單結構給做出來。
這一篇則是將同樣的樹狀結構改使用 Bootstrap 3,雖然不是做出 TreeView,而是使用 Dropdown Menu 的型態將樹狀選單給做出來。
先來回顧一下之前實作樹狀選單的文章:
ASP.NET MVC + jQuery Easy UI Tree 無限階層的樹狀選單
ASP.NET MVC + jQuery Easy UI Tree 無限階層的樹狀選單 - 使用 JSON
ASP.NET MVC 4 + jQuery EasyUI Tree and TreeGrid
再來看看使用 Bootstrap 3 所做出的多層選單的樣子,這邊是直接採用 Bootsnipp 上面一篇由 msurguy 所分享的 snippet,
Viewing snippet Multi level dropdown menu BS3 | Bootsnipp.com
上面是我們要做出來的多層下拉選單的樣子,而我們的多層選單資料就是沿用之前所做的樹狀結構資料,如下:
要怎麼把上面的樹狀結構資料給變成多層下拉選單呢?首先要觀察 Bootstrap 3 Multi Level Dropdown Menu 的 HTML 原始碼(做為一個 Web 開發人員,看懂 HTML 是必須的喔~)
<div class="container">
<div class="row">
<h2>Multi level dropdown menu in Bootstrap 3</h2>
<hr>
<div class="dropdown">
<a id="dLabel" role="button" data-toggle="dropdown" class="btn btn-primary" data-target="#" href="/page.html">
Dropdown <span class="caret"></span>
</a>
<ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">
<li><a href="#">Some action</a></li>
<li><a href="#">Some other action</a></li>
<li class="divider"></li>
<li class="dropdown-submenu">
<a tabindex="-1" href="#">Hover me for more options</a>
<ul class="dropdown-menu">
<li><a tabindex="-1" href="#">Second level</a></li>
<li class="dropdown-submenu">
<a href="#">Even More..</a>
<ul class="dropdown-menu">
<li><a href="#">3rd level</a></li>
<li><a href="#">3rd level</a></li>
</ul>
</li>
<li><a href="#">Second level</a></li>
<li><a href="#">Second level</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
先把 Controller 以及取得樹狀選單資料的方法給做出來,
其實上面的程式在一開始所提到的幾篇文章裡就已經提到。
再來把 Controller 裡面的 Action 方法給補完,
在 Action 方法裡所使用到的 TreeViewModel,如下:
完成 Controller 之後,再來就是建立 View 的部分,
先把 Bootsnipp 上面所提供的 css 複製下來,然後建立一個樣式表檔案然後讓 View 使用,
再來是把 Html 裡面的 Dropdown Menu 部分先複製起來,然後再直接貼到 View 裡,
之前我在「ASP.NET MVC + jQuery Easy UI Tree 無限階層的樹狀選單」這篇文章裡就是使用 @helper 的方式,用遞回的方式將多階層的樹狀選單結構給實作出來,而現在這一篇的 Multi Level Dropdown Menu 也會使用相同的方式來處理,不過 @helper 是無法直接將以前的方法給拿來使用,所以需要再做一個新的,不過結構是差不多的,差別在於一些細節的不同,
@helper GenerateMenu(TreeViewModel model, Guid nodeId)
{
if (model.TreeNodes.All(x => x.ParentID != nodeId))
{
return;
}
var isRoot = nodeId.Equals(model.RootNode.ID);
var multiLevel = isRoot ? "multi-level" : "";
var roleMenu = isRoot ? "menu" : "";
var labelledby = isRoot ? "dropdownMenu" : "";
<ul class="dropdown-menu @(multiLevel)" role="@(roleMenu)" aria-labelledby="@(labelledby)">
@{
var levelNodes = model.TreeNodes
.Where(x => x.ParentID == nodeId)
.OrderBy(x => x.Sort);
}
@foreach (var item in levelNodes)
{
var subMenu = model.TreeNodes.Any(x => x.ParentID == item.ID)
? "dropdown-submenu"
: "";
<li class="@(subMenu)">
<a href="#">@item.Name</a>
@GenerateMenu(model, item.ID)
</li>
}
</ul>
}
再來就是將原本 Dropdown Menu 改使用 @helper
重新整理頁面的執行結果
再比對一下編輯樹狀結構選單的資料
有時候看到蠻多的 ASP.NET WebForm 開發者在轉為使用 ASP.NET MVC 開發的時候,往往碰到最大的障礙就是前端頁面的組成,尤其是對於基礎的 HTML 相當陌生,大概是以往所接觸的都是 Server Controls 的緣故,以往用 Server Controls 都是可以在 Code Behind 去控制前端的行為與顯示結果,但是在 ASP.NET MVC 沒有 Server Controls 卻反而變成這些開發者的夢魘。
其實多多接觸與多多練習是最好的熟悉方式,尤其是在看到一些前端頁面裡的一些功能,再看到這些功能時就可以去思考看看,在 ASP.NET MVC 裡要如何去實作出相似或同樣的功能出來。
以上
真棒 ! 感謝好文~
回覆刪除從TreeGrid教學後,又看到這篇
回覆刪除您的教學一直都是這麼平易近人又貼近現實使用狀況
馬上著手練習跟著一起做選單!
我的文章內容都是從實務專案開發的經驗所衍生而來的
刪除感謝你的回應