AngularJS"手风琴"风格菜单+动态数据+子菜单+使用li ----工作实例

时间:2014-07-10 04:10:46

标签: jquery css angularjs accordion angular-ui-bootstrap

我想要做的是在AngularJS中制作一个带有子菜单的通用手风琴式导航菜单。它必须动态加载菜单数据,动态分配哪些菜单项有子菜单,哪些菜单项没有,等等 - 下面的完整列表。

我尝试过使用angular-ui / bootstrap手风琴元素但不太喜欢它让我能够处理它们的行为。如果我使用< \ accordion>这似乎违反直觉并希望删除手风琴行为。我已经回到使用list-items(< \ li>),因为它允许最灵活/样式。

我想要的是:

  • 动态加载菜单数据
  • 动态加载子菜单数据
  • 动态加载哪些菜单有子菜单,哪些菜单没有
  • 手风琴式:点击一个带子菜单的菜单项,将关闭另一个子菜单。
  • 每个端点菜单都是一个链接:如果菜单没有子菜单,则为链接 - >导航 - 如果菜单中有子菜单,则会打开其子菜单,并且不会导航。
  • 单击菜单区域,将折叠所有子菜单。
  • 状态感知:应该知道哪个菜单处于活动状态,允许我们在活动菜单项上设置class =“active({{menuItem.url}})”type thing。
  • 子菜单识别:我们应该能够向上/向下/向左/向右添加V形符号以指示哪个菜单元素具有子菜单 - 以及子菜单处于哪种状态(打开/关闭)。
  • 尽可能在CSS / HTML中完成,应该是。


基于此帖:Closing open submenu - jQuery accordion 我在jQuery中有一个工作版本 - 在这里小提琴:http://jsfiddle.net/52EH8/20/

function initMenu() {
     $('#nav ul').hide();
     $('#nav li a').click(

     function () {

         var checkElement = $(this).next();
         if ((checkElement.is('ul')) && (checkElement.is(':visible'))) {
             $('#nav ul:visible').slideToggle('normal');
         }
         if ((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
             removeActiveClassFromAll();
             $(this).addClass("active");
             $('#nav ul:visible').slideToggle('normal');
             checkElement.slideToggle('normal');
             return false;
         }

         if($(this).siblings('ul').length==0 && $(this).parent().parent().attr('id')=='nav')
         {

             removeActiveClassFromAll();
             $(this).addClass("active");
             $('#nav ul:visible').slideToggle('normal');

             return false;
         }
     });
 }

 function removeActiveClassFromAll() {
     $('#nav li a').each(function (index) {
         $(this).removeClass("active");
     });
 }


 $(document).ready(function () {
     initMenu();
 });

 $('#nav').click(function (e)

 {
     e.stopPropagation();


 })




 $(document).click(function () {
     $('#nav').children('li').each(function () {
         if ($(this).children('ul').css('display') == 'block') {
             $(this).children('ul').slideToggle('normal')
             $(this).children('a').removeClass('active')
         }
     })
 })

我的JSON菜单(咖啡脚本)是:

S.mainMenu = [
        name: 'Home'
        url: 'home'
        icon: 'fa-home'
    ,
        name: 'Events'
        url: 'events'
        icon: 'fa-bullhorn'
    ,
        name: 'Jobs'
        url: 'jobs'
        icon: 'fa-laptop'
    ,
        name: 'Resources'
        icon: 'fa-cloud-download'
        submenu: [
            name: 'Guides & Tutorials'
            url: 'res-guides'
            icon: 'fa-lightbulb-o'
        ,
            name: 'Docs & Templates'
            url: 'res-docs'
            icon: 'fa-file-text'
        ,
            name: 'Photos & Video'
            url: 'res-media'
            icon: 'fa-film'
        ]
    ,
        name: 'TechGrind'
        icon: 'fa-cogs'
        submenu: [
            name: 'Startup Hubs'
            url: 'tg-hubs'
            icon: ''
        ,
            name: 'Membership'
            url: 'tg-members'
            icon: ''
        ,
            name: 'Community'
            url: 'tg-activities'
            icon: ''
        ,
            name: 'Incubator'
            url: 'tg-incubator'
            icon: ''
        ]
    ];

如您所见 - 有3个普通菜单和2个菜单子菜单。

或多或少 - 如何正确地将其从jQuery转换为“思考Angular”? ATM我的主要问题是:在哪里正确放置$(document).ready来触发initMenu()??

我有一种强烈的感觉,这应该全部放入指令中,但是 - 或2指令(1 =顶级手风琴菜单,2 =子菜单)。我对指令不太满意,但这是我的问题。

我见过很多关于这种类型菜单的帖子 - 对于我认为制作一个通用的,动态加载的,X个菜单,Y个子菜单等等的人来说,这将是有益的。我已经格式化了我的问题ACCORDINgly(双关语),以便它可以满足所有需求。

提前致谢!

2 个答案:

答案 0 :(得分:1)

如果您已经使用Bootstrap进行样式设计,我强烈建议您使用Angular-UI Bootstrap。使用此模块,您不必重新发明轮子。只需查看this example,它基于文档中的Accordion示例。

答案 1 :(得分:1)

这是一个基于bootstrap崩溃插件的角度指令。它使用零jQuery,你可以根据需要进一步自定义。

Demo Plunker

手风琴行为依赖于Bootstrap的以下模板:

<div id="parent">
    <div class="panel">
        <div data-toggle="collapse" data-parent="#parent" data-target="#child">test</div>
        <div id="child" class="collapse in">
            This is the content
        </div>
    </div>
    <div class="panel">
        <div data-toggle="collapse" data-parent="#parent" data-target="#child2">test</div>
        <div id="child2" class="collapse">
            This is the content
        </div>
    </div>
</div>