1.3 菜单管理 (系统开发架构与设计步步谈)
1.3 菜單管理
一個(gè)系統(tǒng)開發(fā)一段時(shí)間以后,或者用戶試用一段時(shí)間以后,會(huì)發(fā)現(xiàn),原來有些頁面不用了,有些菜單不需要了。在我們開發(fā)過程中都會(huì)有開發(fā)環(huán)鏡、測試環(huán)鏡、正式環(huán)鏡,如果菜單條目經(jīng)常變動(dòng),保持菜單及文件在各個(gè)環(huán)鏡同步是個(gè)比較麻煩的事情,特別是那些前期項(xiàng)目需求分析的不到位的項(xiàng)目,一會(huì)刪掉一個(gè),一會(huì)新增一個(gè)。對(duì)此我們的系統(tǒng)需要額外的輔助工具來做這件事情
通常情況下,菜單表都設(shè)計(jì)為自關(guān)聯(lián)表,如下表
|
字段名 |
類型 |
|
|
Id |
Varchar(20) |
|
|
Parented |
Varchar(20 |
|
|
url |
Varchar(50) |
|
|
isUsed |
bit |
此處的id不可用自增的形式,應(yīng)為程序生成的序列號(hào),以方便日后生成菜單腳本
一般C#程序顯示菜單示例代碼為,源自《ASP.NET2.0 Unleashed》
/// <summary>
/// Get the data from the database and create the top-level
/// menu items
/// </summary>
private void PopulateMenu()
{
DataTable menuData = GetMenuData();
AddTopMenuItems(menuData);
}
/// <summary>
/// Use a DataAdapter and DataTable to grab the database data
/// </summary>
/// <returns></returns>
private DataTable GetMenuData()
{
// Get Categories table
string selectCommand = "SELECT CategoryId,ParentId,Name FROM Categories";
string conString = WebConfigurationManager.ConnectionStrings["Categories"].ConnectionString;
SqlDataAdapter dad = new SqlDataAdapter(selectCommand, conString);
DataTable dtblCategories = new DataTable();
dad.Fill(dtblCategories);
return dtblCategories;
}
/// <summary>
/// Filter the data to get only the rows that have a
/// null ParentID (these are the top-level menu items)
/// </summary>
private void AddTopMenuItems(DataTable menuData)
{
DataView view = new DataView(menuData);
view.RowFilter = "ParentID IS NULL";
foreach (DataRowView row in view)
{
MenuItem newMenuItem = new MenuItem(row["Name"].ToString(), row["CategoryId"].ToString());
Menu1.Items.Add(newMenuItem);
AddChildMenuItems(menuData, newMenuItem);
}
}
/// <summary>
/// Recursively add child menu items by filtering by ParentID
/// </summary>
private void AddChildMenuItems(DataTable menuData, MenuItem parentMenuItem)
{
DataView view = new DataView(menuData);
view.RowFilter = "ParentID=" + parentMenuItem.Value;
foreach (DataRowView row in view)
{
MenuItem newMenuItem = new MenuItem(row["Name"].ToString(), row["CategoryId"].ToString());
parentMenuItem.ChildItems.Add(newMenuItem);
AddChildMenuItems(menuData, newMenuItem);
}
}
自關(guān)聯(lián)表需要遞歸算法。
到這里實(shí)現(xiàn)了菜單的設(shè)計(jì),還沒有解決開始提出來的問題,保持測試環(huán)鏡、正式環(huán)鏡同步。實(shí)現(xiàn)的思路很多,我這里想說的就有兩種。
一種是不用數(shù)據(jù)庫設(shè)計(jì)菜單了,而是所有菜單只保存在一個(gè)XML文件中,每次變更只需要變更XML文件即可,去更新測試環(huán)鏡、生產(chǎn)環(huán)鏡也只要更新一個(gè)菜單文件即可
另一種用數(shù)據(jù)庫設(shè)計(jì)菜單,如果由于設(shè)計(jì)變更,刪除以前的菜單和新增了新的菜單,可以做門的開發(fā)輔助工具完成,再針對(duì)目前的菜單生成SQL腳本,用腳本來更新測試、生產(chǎn)環(huán)鏡,如果開發(fā)輔助工具要是做的更好,可以專門在項(xiàng)目里做個(gè)頁面來做更新菜單功能。更新的思路是刪除以前的菜單,然后再完整新增菜單條目。生成腳本的存儲(chǔ)過程可以參考我以前的日志《SQL Server 2008 生成數(shù)據(jù)腳本》
總結(jié)
以上是生活随笔為你收集整理的1.3 菜单管理 (系统开发架构与设计步步谈)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 尿多是什么原因(“尿多”和“尿少”是什么
- 下一篇: Linux 查看 CPU 物理/逻辑 核