最近在做的一個ROR的web項目中遇到如下問題:
產品可以按類分類導航浏覽,主要可以分為A,B,C三類,三類之下還有其他分類,同時,基類和其下 的分類都可以由用戶擴展。從橫向上,主類可以由用戶擴展,縱向上,用戶也可以擴展。
類別信息存儲與categories表中:
id:integer 主鍵
name:string 類別名稱
parentid:integer 類別的父類
要求:
生成導航菜單,並且可以含有子類的菜單可以通過點擊展開或關閉,並且可以按類別導航產品。
實現Ruby on Rails導航菜單:
通過深度優先遍歷來生成菜單,在便利過程中構建菜單的html編碼,主要是使用了一個@htmlmenu的 string來拼接生成的html代碼,最終顯示在頁面中。
Ruby on Rails導航菜單代碼:
def index
@htmlmenu=""
@htmlmenu+= "< ul>"
@root = Category.find(:all,:conditions=>['parentid=0'])
@root.each { |item|
if Category.find_by_parentid(item.id)
@htmlmenu+= "< li>< a href='#ChildMenu#{item.id}' onclick=\"DoMenu
('ChildMenu#{item.id}')\">"
else
@htmlmenu+= "< li>< a href='/categories/#{item.id}'>"
end
@htmlmenu+= item.name
@htmlmenu+= "< /a>"
buildmenu item
@htmlmenu+= "< /li>"
}
@htmlmenu+= "< /ul>"
end
private
def buildmenu category
@children = Category.find_all_by_parentid(category.id)
if @children.size!=0
@htmlmenu+= "< ul id='ChildMenu#{category.id}' class='collapsed'>"
@children.each { |item|
if Category.find_all_by_parentid(item.id).size!=0
@htmlmenu+= "< li>< a href='#ChildMenu#{item.id}'
onclick=\"DoMenu('ChildMenu#{item.id}')\">"
else
@htmlmenu+= "< li>< a href='/categories/#
{item.id}'>"
end
@htmlmenu+= item.name
@htmlmenu+= "< /a>"
buildmenu item
@htmlmenu+= "< /li>"
}
@htmlmenu+= "< /ul>"
end
end
遍歷方法為private的buildmenu方法。
說明:parentid=0是為了找到所有的基類,他們的parentid默認為0;
在代碼中需要加入css和js:
< script type="text/javascript">
function DoMenu(emid){
var obj = document.getElementById(emid);
obj.className = (obj.className.toLowerCase() ==
"expanded"?"collapsed":"expanded");
}
-->
< /script>
< style>
ul.collapsed {
display: none;
}
< /style>
有關Ruby on Rails導航菜單的補充:
1.這是一個雛形,關於性能問題有以下幾點:
1.1 代碼可以優化,有些比較判斷沒有必要,懶得去掉了:)
1.2 如果類別數據增多,如果擔心過多的數據庫訪問,可以把這些寫到程序初始化裡去,不過缺點 是新增的類別需要重啟服務器後可以生效
2.我覺得這個拿去做文件系統遍歷很好,而且可以直接生成html頁面~