最近在做的一個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頁面~