2016-07-14 18 views
3

私はこのダイナミックメニューを現在よりも洗練された方法で動かす方法について頭を悩ましています。現在、フラットなXML構造としてメニュー項目のリストを受け取ります。マルチレベルメニュー

私はデータがオブジェクトの内側にどのように見えるかを示す以下のオブジェクトを作成し、それは各メニュー項目の親子関係を持っている(私は読みやすくするためにインデントしました)

let Menu = [ 
    { 
    DisplayName : "Menu1", 
    href   : "Menu1.aspx", 
    MenuID  : "1", 
    ParentMenuID : "?", 
    Position  : "1", 
    UserTypeCode : "99" 
    }, 
     { 
     DisplayName : "Menu-1-1", 
     href   : "Menu1.aspx", 
     MenuID  : "2", 
     ParentMenuID : "1", 
     Position  : "1", 
     UserTypeCode : "99" 
     }, 
     { 
     DisplayName : "Menu-1-2", 
     href   : "Menu1.aspx", 
     MenuID  : "3", 
     ParentMenuID : "1", 
     Position  : "2", 
     UserTypeCode : "99" 
     }, 
    { 
    DisplayName : "Menu2", 
    href   : "Menu2.aspx", 
    MenuID  : "4", 
    ParentMenuID : "?", 
    Position  : "2", 
    UserTypeCode : "99" 
    }, 
     { 
     DisplayName : "Menu2-1", 
     href   : "Menu1.aspx", 
     MenuID  : "5", 
     ParentMenuID : "4", 
     Position  : "1", 
     UserTypeCode : "99" 
     }, 
     { 
     DisplayName : "Menu2-2", 
     href   : "Menu1.aspx", 
     MenuID  : "6", 
     ParentMenuID : "4", 
     Position  : "2", 
     UserTypeCode : "99" 
     }, 
      { 
      DisplayName : "Menu2-2-1", 
      href   : "Menu1.aspx", 
      MenuID  : "7", 
      ParentMenuID : "6", 
      Position  : "1", 
      UserTypeCode : "99" 
      } 
]; 

私はどのように私のメニューの各レベルのために別の関数を必要とする私の現在のやや厄介なソリューションなしで(私は理想的と思われる再帰関数を使用して)メニューオブジェクトを動的に作成することができます知っています。分、それは3つのレベルのメニューに限定されています

私が望むのは受け入れられる素晴らしい機能ですすべてのヘルプははるかに高く評価されるだろうhttp://pastebin.com/ektBQ7kd

:メニューレベル

function createRoot(){ 

    // Initially map all root elements 
    Menu.map((item, index) => { 

     if (item.ParentMenuID === "?"){ 

      // If the the next menu item is a child of this root 
      if (Menu[index+1].ParentMenuID === item.MenuID){ 

       // Generate boilerplate dropdown code + then retrieve it's children 
       htmlStr += `<li class="dropdown-submenu"><a class="test" data-menuID="`+item.MenuID+`" data-menuitem="`+item.href+`" href="#">`+item.DisplayName+`<span class="caret"></a>` 
        htmlStr += `<ul class="dropdown-menu">` 
         GetLevel1(item); 
        htmlStr += `</ul>` 
       htmlStr += `</li>` 

      // Otherwise it's just a normal menu item 
      } else { 
       htmlStr += `<li><a class="test" data-menuID="`+item.MenuID+`" data-menuitem="`+item.href+`" href="#">`+item.DisplayName+`</a></li>` 
      } 
     } 


    }); 

    $('#user-menu-list').html(htmlStr); 

     // Setup event on list items 
     $('.dropdown-submenu a.test').on("click", function(e){ 
     $(this).next('ul').toggle(); 
     e.stopPropagation(); 
     e.preventDefault(); 
     }); 
} 

function GetLevel1(item){ 

    Menu.map((subItem, index) => { 

     if (index < Menu.length-1){ 
     console.log(index); 
      // If the current item is a child of the root 
      if (subItem.ParentMenuID === item.MenuID){ 
       // If the the next item is a child of this root 
       if (Menu[index+1].ParentMenuID === subItem.MenuID){ 
        htmlStr += `<li class="dropdown-submenu"><a class="test" data-menuID="`+subItem.MenuID+`" data-menuitem="`+subItem.href+`" href="#">`+subItem.DisplayName+`<span class="caret"></a>` 
         htmlStr += `<ul class="dropdown-menu">` 
          GetLevel2(subItem); 
         htmlStr += `</ul>` 
        htmlStr += `</li>` 
       } else { 
        htmlStr += `<li><a class="test" data-menuID="`+subItem.MenuID+`" data-menuitem="`+subItem.href+`" href="#">`+subItem.DisplayName+`</a></li>` 
       } 
      } 

     } 


    }); 
} 

function GetLevel2(item){ 

    Menu.map((subItem, index) => { 

     console.log("INDEX: "+index); 
     // If the current item is a child of the root 
     if (subItem.ParentMenuID === item.MenuID){ 
      htmlStr += `<li><a class="test" data-menuID="`+subItem.MenuID+`" data-menuitem="`+subItem.href+`" href="#">`+subItem.DisplayName+`</a></li>` 
     } 
    }); 
} 

createRoot(); 

の任意の数は、ここに私のメニューは分で働くとの完全なペーストビンリンクです!

+0

再帰関数は、ここで良いようです。 – Chris

+0

それは私が本当に後に何をしているのですが、私はこの場合どのようにそれを行うかを理解できません –

答えて

0

私の再帰的な能力は少し改善されていますが、 私はこのようなことをします 最初にすべてのメニューを行って、両親に子供メニューを追加します。

フェーズ1が完了し、メニューとサブメニューが1つのオブジェクトにある場合、再帰的に再作成してメニューを作成できます。このような

何か:

var Menu = [{ 
 
    DisplayName: "Menu1", 
 
    href: "Menu1.aspx", 
 
    MenuID: "1", 
 
    ParentMenuID: "?", 
 
    Position: "1", 
 
    UserTypeCode: "99" 
 
}, { 
 
    DisplayName: "Menu-1-1", 
 
    href: "Menu1.aspx", 
 
    MenuID: "2", 
 
    ParentMenuID: "1", 
 
    Position: "1", 
 
    UserTypeCode: "99" 
 
}, { 
 
    DisplayName: "Menu-1-2", 
 
    href: "Menu1.aspx", 
 
    MenuID: "3", 
 
    ParentMenuID: "1", 
 
    Position: "2", 
 
    UserTypeCode: "99" 
 
}, { 
 
    DisplayName: "Menu2", 
 
    href: "Menu2.aspx", 
 
    MenuID: "4", 
 
    ParentMenuID: "?", 
 
    Position: "2", 
 
    UserTypeCode: "99" 
 
}, { 
 
    DisplayName: "Menu2-1", 
 
    href: "Menu1.aspx", 
 
    MenuID: "5", 
 
    ParentMenuID: "4", 
 
    Position: "1", 
 
    UserTypeCode: "99" 
 
}, { 
 
    DisplayName: "Menu2-2", 
 
    href: "Menu1.aspx", 
 
    MenuID: "6", 
 
    ParentMenuID: "4", 
 
    Position: "2", 
 
    UserTypeCode: "99" 
 
}, { 
 
    DisplayName: "Menu2-2-1", 
 
    href: "Menu1.aspx", 
 
    MenuID: "7", 
 
    ParentMenuID: "6", 
 
    Position: "1", 
 
    UserTypeCode: "99" 
 
}]; 
 

 
var main = []; 
 

 
function getSiblins(currentNode, currentId) { 
 
    if (!currentId) { 
 
    currentNode.children = currentNode.children || new Array(); 
 
    return getSiblins(currentNode, currentNode.MenuID) 
 
    } else { 
 
    for (var j = 0; j < Menu.length; j++) { 
 
     if (Menu[j].ParentMenuID == currentId) { 
 
     currentNode.children.push(Menu[j]); 
 
     } 
 
    } 
 
    } 
 

 
    if (currentNode.ParentMenuID == "?") { 
 
    //root menu 
 
    main.push(currentNode); 
 
    } 
 
} 
 

 
for (var i = 0; i < Menu.length; i++) 
 
    getSiblins(Menu[i]); 
 

 
function prepareMenu(currentMenu) { 
 
    var appendHtml = "<li>" + currentMenu.DisplayName + "</li>" 
 
    for (var i = 0; i < currentMenu.children.length; i++) { 
 
    appendHtml = appendHtml + "<ul class='children'>" + prepareMenu(currentMenu.children[i]) + "</ul>"; 
 
    } 
 

 
    return appendHtml; 
 
} 
 

 
var menuHtml = ""; 
 
for (var j = 0; j < main.length; j++) { 
 
    menuHtml += prepareMenu(main[j]); 
 
} 
 

 
document.getElementById("finalMenu").innerHTML = menuHtml;
.children li{ 
 
    color: blue; 
 
} 
 

 
.children .children li { 
 
    color: green; 
 
}
<ul id="finalMenu"> 
 

 
</ul>

+0

それは完璧なおかげです! –

関連する問題