สวัสดีค่ะวันนี้เรามาว่ากันเรื่องเมนูกันดีกว่านะคะ คำว่าเมนู ผู้เขียนคิดว่าทุกคนต้องรู้จักแน่นอน เพราะในการพัฒนาแต่ละระบบนั้นส่วนใหญ่จะมีส่วนของงานหลายๆส่วน ทำให้มีการออกแบบหน้าจอการใช้งานหลายหน้าจอเพื่อรองรับการทำงานของระบบนั้น เมื่อส่งมอบระบบ แน่นอน!! ค่ะ ความต้องการของลูกค้าไม่หยุดแค่นั้นแน่นอน เมื่อความต้องการเพิ่ม การทำงานของหน้าจอก็เพิ่ม เมนูก็ต้องเพิ่มตามมาเช่นกัน ทำให้ผู้พัฒนาต้องไปแก้โค้ดในส่วนของเมนูทุกครั้งที่มีการเพิ่มเมนู การจัดหมวดหมูของเมนู หรือต้องการปรับเปลี่ยน 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 เพื่อจัดการเมนู
จากรูปจะเป็นตัวอย่างของเมนูที่มีเมนูย่อย โดยมีเมนูหลักเป็น Parent ในรูป คือ testsub2 โดยมีลูก(Child) เป็น jar2 และ jar และ jar ก็เป็น Parent โดยมี testSub เป็นลูก(Child) อีกครั้ง จะเห็นว่าไม่ว่าจะต้องการให้มีเมนูย่อยแค่ไหน Recursive ก็สามารถทำเราง่ายในการจัดการมากขึ้น โดยไม่ต้องมา copy code วางหลายๆครั้งให้ยุ่งยากอีกต่อไปค่ะ และที่สำคัญในตัวอย่างเราจะดึงข้อมูลเมนูมาจากฐานข้อมูล ไม่ว่าเราจะเพิ่มเมนู หรือเปลี่ยน path หรือเพิ่มเมนูย่อยในเมนูหลักลงลึกแค่ไหน เราก็ไม่ต้องมาเสียเวลานั่งแก้โค้ดในหน้าของเมนูอีกต่อไปแล้วนะคะ ผู้อ่านท่านใดมีการจัดเมนูหลายเมนู ลองนำไปปรับใช้กันดูนะคะ ขอบคุณค่ะ^^
แหล่งอ้างอิง
https://stackoverflow.com/questions/35326302/unlimited-multi-level-menu-in-mvc