Unlimited multi level menu in mvc
สวัสดีค่ะวันนี้เรามาว่ากันเรื่องเมนูกันดีกว่านะคะ คำว่าเมนู ผู้เขียนคิดว่าทุกคนต้องรู้จักแน่นอน เพราะในการพัฒนาแต่ละระบบนั้นส่วนใหญ่จะมีส่วนของงานหลายๆส่วน ทำให้มีการออกแบบหน้าจอการใช้งานหลายหน้าจอเพื่อรองรับการทำงานของระบบนั้น เมื่อส่งมอบระบบ แน่นอน!! ค่ะ ความต้องการของลูกค้าไม่หยุดแค่นั้นแน่นอน เมื่อความต้องการเพิ่ม การทำงานของหน้าจอก็เพิ่ม เมนูก็ต้องเพิ่มตามมาเช่นกัน ทำให้ผู้พัฒนาต้องไปแก้โค้ดในส่วนของเมนูทุกครั้งที่มีการเพิ่มเมนู การจัดหมวดหมูของเมนู หรือต้องการปรับเปลี่ยน path ที่ไปเรียกหน้าจอนั้นๆ แค่คิดก็ดูยุ่งยากต่อการจัดการแล้ว วันนี้ผู้เขียนจึงนำวิธีการออกแบบและพัฒนาในส่วนของเมนูที่ผู้เขียนได้ใช้พัฒนาใน MVC มาเป็นตัวอย่างให้ดูกันนะคะ สำหรับผู้อ่านที่ไม่ได้ใช้ MVC ก็สามารถนำไปปรับเปลี่ยนได้ค่ะ หลังจากพัฒนาแล้วระบบก็จะสามารถ เพิ่มเมนู หรือเปลี่ยน path ของเมนู หรือ จัดการกลุ่มของเมนู ได้โดยไม่ต้อง publish ระบบ ทุกครั้งที่มีการแก้ไข ทำให้ง่ายและไม่เสียเวลาในการจัดการเลยค่ะ เรามาเริ่มกันเลยค่ะ ผู้เขียนขอแบ่งการพัฒนาเป็นสองส่วนนะคะ คือ 1.การพัฒนาในฐานข้อมูล : ในส่วนของการออกแบบฐานข้อมูลผู้อ่านต้องออกแบบให้มีการเก็บ id ของ parent เพื่อระบุให้รู้ว่าเมนูตัวนี้เป็นลูกของเมนูตัวไหน ตัวอย่างการออกแบบฐานข้อมูลของเมนู คอลัมภ์ คำอธิบาย ParentID Id ของ parent MenuID Id ของเมนู MenuName ชื่อของเมนู 2.การพัฒนาระบบ : เป็นการพัฒนาระบบผู้เขียนจะใช้วิธีการพัฒนาแบบใช้ Recursive เข้ามาจัดการในส่วนของการแสดงเมนู โดยข้อดีของ Recursive คือเราสามารถจัดการได้ทั้งส่วนที่มีเมนูย่อย และไม่มีเมนูย่อย ตัวอย่างในส่วนของ Recursive ที่ใช้ใน View เพื่อการแสดงเมนู ( MVC) @helper GetSubMenus(IEnumerable<menutable> siteMenu, Nullable<int> parentID) { foreach (var i in Model.Where(a => a.ParentID.Equals(parentID))) { var submenu = Model.Where(a => a.ParentID.Equals(i.MenuID)).Count(); <li class=”@(submenu > 0 ? “dropdown-submenu” : “dropdown”)”> <a href=”@(!string.IsNullOrEmpty(i.MenuLink) ? Url.Content(i.MenuLink) : “~/default)” style=”font-size:16px;”>@i.MenuName</a> @if (submenu > 0) { <ul class=”dropdown-menu”> @GetSubMenus(siteMenu, i.MenuID) @* Recursive Call for Populate Sub items here*@ </ul> } </li> } } @{ var mymenu = @Model; var menuParentID = mymenu.First().ParentID; } @if (mymenu != null && mymenu.Count() > 0) { <nav class=”navbar navbar-default”> <div class=”container-fluid”> <div class=”collapse navbar-collapse” id=”bs-example-navbar-collapse-1″> <ul class=” nav navbar-nav”> @GetSubMenus(mymenu, menuParentID) </ul> </div> </div> </nav> } ตัวอย่างหน้าจอของเมนูที่เรียกใช้ Recursive เพื่อจัดการเมนู