AngularJS多级下拉菜单从递归指令生成的菜单结构 [英] AngularJS multilevel dropdown menu for a menu structure generated from a recursive directive

查看:1563
本文介绍了AngularJS多级下拉菜单从递归指令生成的菜单结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个泡菜的显眼位置。
我从一个Web服务调用让我多级导航菜单。

I have a dilly of a pickle here. I have to get my multi-level navigation menu from a webservice call.

由于我的导航菜单可以有子在它的无限量,我不得不用递归指令来建立我的父/子导航结构。
我现在想弄清楚如何把它变成一个功能dropmenu结构。
我正在看angularui自举,他们有一个
下拉切换,其中有一些基本的功能dropmenu,但由于
我用我的菜单结构已经产生了CSS angularjs递归指令
类附着到它们。该angularjs-引导dropmenu的有
CSS类这比我angularjs生成的类不同....看哪!

Since my navigation menu can have an infinite amount of submenu's in it, I had to use a recursive directive to build my parent/child navigation structure. Now I am trying to figure out how to turn it into a functional dropmenu structure. I was taking a look at angularui-bootstrap, and they have a Dropdown Toggle, which has some basic dropmenu functionality, but since I used a recursive directive my menu structure already has angularjs generated css classes attached to them. The angularjs-bootstrap dropmenu's have css classes which are different than my angularjs generated classes....behold!

<ul>
    <li ng-repeat="parent in parents" class="ng-scope">
        <recursive-list-item on-node-click="onNodeClickFn(node)" parent="parent" class="ng-isolate-scope ng-scope">
            <a data-ng-click="onNodeClick({node: parent})" href="javascript:void(0)" class="ng-scope ng-binding">Clothes</a>
            <!-- ngIf: parent.children.length > 0 -->
            <ul data-ng-if="parent.children.length &gt; 0" class="ng-scope">
                <!-- ngRepeat: child in parent.children -->
                <li ng-repeat="child in parent.children" class="ng-scope">
                    <recursive-list-item data-on-node-click="onNodeClickFn(node)" data-parent="child" class="ng-isolate-scope ng-scope">
                        <a data-ng-click="onNodeClick({node: parent})" href="javascript:void(0)" class="ng-scope ng-binding">Gortex Jackets</a>
                        <!-- ngIf: parent.children.length > 0 -->
                    </recursive-list-item>
                </li>
                <!-- end ngRepeat: child in parent.children -->
                ...
                ...
                ...
            </ul>
        </recursive-list-item>
    </li>
    <!-- end ngRepeat: child in parent.children -->
...
...
</ul>

这是被作为用于我的递归导航菜单的最终输出中产生的HTML的一个例子。有它成立这样子所有的NG-点击的是活动的,并且它们具有相同的范围,作为主控制器(全部是花花公子,除了它看起来并不像一个dropmenu)

That was an example of the html that is generated as the final output for my recursive navigation menu. Having it set up this way all submenu's ng-click's are active, and they have the same scope as the main controller (all is dandy except it doesn't look like a dropmenu)

下面是dropmenu结构angularjs自举

Here is an example of the dropmenu structure for angularjs-bootstrap

<li class="dropdown" ng-controller="DropdownCtrl">
  <a class="dropdown-toggle">
    Click me for a dropdown, yo!
  </a>
  <ul class="dropdown-menu">
    <li ng-repeat="choice in items">
      <a>{{choice}}</a>
    </li>
  </ul>
</li>

它有很多不同的CSS类结构比我,所以angularjs自举的下拉不会与我的工作。

It has very much different css class structure than mine, so angularjs-bootstrap's 'dropdown' won't work with mine.

有没有人对我有什么建议吗?请记住,因为我通过一个Web服务调用通过JSON得到我的导航结构我必须使用递归angularjs以创建父/子菜单结构。

Does anyone have any suggestions for me? Keep in mind that since I am getting my navigation structure via json via a webservice call I have to use recursive angularjs in order to create the parent/child menu structure.

如果有人感到困惑产生在这里我可以告诉我的自定义指令code我的指令HTML,但不会,除非要求简洁。我的自定义指令code工程只是建立导航结构,并保持所有连接到主控制器的范围指令范围(即:点击激活),但它不是风格/滚动活跃

If anyone is confused about my directive html generated here I can show my custom directive code, but will not unless asked for brevity. My custom directive code works for just building the navigation structure, and keeps all the directive scopes connected to the main controller's scope (ie: click active), but it is not styled/scroll active.

的* UPDATE *的 * 的**
我创建了一个plunker复制几乎是一样的。
在项目中,我是从一个angularjs服务让我的导航菜单的数据,
这将使一个Web服务调用到我的服务器上的web服务休息,但我没有,在这里,所以我只是手动创建的JSON,使得web服务REST调用我服务的每一个。
最重要的部分是递归的指令。
正下方你会发现链接到plunker项目。
有人可以帮我吗?

*UPDATE**** I have created a plunker replication that is almost the same. In my project I was getting my navigation menu data from an angularjs service, which would make a webservice call to a rest webservice on my server, but I don't have that here, so I just manually created the json for each one of my services that makes REST webservice calls. The important part is the recursive directive. Right below you will find the link to the plunker project. Can someone help me out?

Plunker项目 ----------- --------------------------------------------------

Plunker Project -------------------------------------------------------------

的**的 * 的* 较新的更新 * 的**的 * 的****
从Charlietfl说我可以在我的导航dropmenu结构多个CSS类评论。我与angularui自举尝试此。我跟着添加这到我的项目的指示,创建基于旧plunker项目中的新项目Plunker,但添加到导航结构的额外dropmenu CSS类。这里是Plunker项目: Plunker项目

****NEWER UPDATE******** Comment from Charlietfl that I can just have multiple css classes in my navigation dropmenu structure. I am attempting this with angularui-bootstrap. I followed the instructions for adding this to my project and created a new Plunker project based on the old plunker project, but with the extra dropmenu css classes added to the navigation structure. Here is the Plunker Project: Plunker Project

导航元素仍然出现在DOM,但他们是不可见的。
我看着CSS的第一个ul元素,它是这样:

The navigational elements still show up in the DOM but they are not visible. I looked at the css for the first ul element and it is as such:

*, *:before, *:after {
    -moz-box-sizing: border-box;
}
*, *:before, *:after {
    -moz-box-sizing: border-box;
}
.dropdown-menu {
    background-clip: padding-box;
    background-color: #FFFFFF;
    border: 1px solid rgba(0, 0, 0, 0.15);
    border-radius: 4px;
    box-shadow: 0 6px 12px rgba(0, 0, 0, 0.176);
    display: none;
    float: left;
    font-size: 14px;
    left: 0;
    list-style: none outside none;
    margin: 2px 0 0;
    min-width: 160px;
    padding: 5px 0;
    position: absolute;
    top: 100%;
    z-index: 1000;
}

这是从官方的引导css文件获得。
不知道到底为什么它是不可见的。
不知道这是否会帮助,但这里是针对UL

It was obtained from the official bootstrap css file. Not sure exactly why it's not visible. Not sure if it will help, but here is the css for the very next li element after the ul

*, *:before, *:after {
    -moz-box-sizing: border-box;
}
*, *:before, *:after {
    -moz-box-sizing: border-box;
}
.dropdown {
    position: relative;
}
.dropup, .dropdown {
    position: relative;
}
li {
    line-height: 20px;
}
*, *:before, *:after {
    -moz-box-sizing: border-box;
}

请记住,你必须去到plunker页面查看更新code从我加入需要angularui-引导的CSS标签开始。
看到无形的导航元素,你会需要像萤火虫看到了DOM。

Keep in mind that you have to go to the plunker page to see the updated code starting from when I added the css tags needed for angularui-bootstrap. To see the invisible navigational elements you will need something like Firebug to see the DOM.

下面是从我的更新一些HTML最终输出(从DOM)的例子,试图与angularui自举CSS类工作。

Here is an example of some html final output (from the DOM) from my update to try and work with angularui-bootstrap css classes.

...
<li ng-repeat="child in parent.children" class="dropdown ng-scope">
            <recursive-list-item data-on-node-click="onNodeClickFn(node)" data-parent="child" class="ng-isolate-scope ng-scope">
            <a class="dropdown-toggle ng-scope ng-binding" href="javascript:void(0)">Kids Clothes</a>
...

我怀疑是angularui自举libary不工作的原因是因为了递归列表项..元素是礼元素的子元素,父元素的一元件。难道这预感我的修正?

I suspect that the reason the angularui-bootstrap libary is not working is because of the "recursive-list-item.." element that is a child element of the "li" element, and parent element to the "a" element. Is this hunch of mine correct?

推荐答案

这是我用的,它有很多额外的功能是pretty甜蜜。
请参阅使用 $ scope.menu 和什么,当你展开下拉发生 - 你可以把头,分频器,甚至附上单击功能。请注意,您可以嵌套许多 UL 只要你想,虽然切换工作,它是无用的,因为点击打开子菜单会隐藏其父。据我所知,你需要创建自己的JavaScript处理程序或自定义CSS,如果你想在菜单中嵌套较深徘徊使用。

This is what I use and it has a lot of extra functionality that is pretty sweet. See the usage $scope.menu and what happens when you expand the dropdown - you can put in headers, dividers, and even attach click functions. Note that you can nest as many ul as you want, and though toggle does work, it's useless since clicking to open a submenu will hide its parent. As far as I know, you would need to create your own javascript handler or custom css using hovers if you want deeper nesting in the menu.

住在这里的演示(点击进入)。

<nav>
  <div menu="menu"></div> <!-- the element here doesn't matter -->
</nav>

JS:

var app = angular.module('myApp', ['ui.bootstrap']);

app.directive('menu', function() {
  return {
    restrict: 'A',
    scope: {
      menu: '=menu',
      cls: '=ngClass'
    },
    replace: true,
    template: '<ul><li ng-repeat="item in menu" menu-item="item"></li></ul>',
    link: function(scope, element, attrs) {
      element.addClass(attrs.class);
      element.addClass(scope.cls);
    }
  };
});

app.directive('menuItem', function($compile) {
  return {
    restrict: 'A',
    replace: true,
    scope: {
      item: '=menuItem'
    },
    template: '<li active-link><a href={{item.href}}>{{item.title}}</a></li>',
    link: function (scope, element, attrs) {
      if (scope.item.header) {
        element.addClass('nav-header');
        element.text(scope.item.header);
      }
      if (scope.item.divider) {
        element.addClass('divider');
        element.empty();
      }
      if (scope.item.submenu) {
        element.addClass('dropdown');

        var text = element.children('a').text();
        element.empty();
        var $a = $('<a class="dropdown-toggle">'+text+'</a>');
        element.append($a);

        var $submenu = $('<div menu="item.submenu" class="dropdown-menu"></div>');
        element.append($submenu);
      }
      if (scope.item.click) {
        element.find('a').attr('ng-click', 'item.click()');
      }
      $compile(element.contents())(scope);
    }
  };
});

app.controller('myCtrl', function($scope) {
  $scope.menu = [
    {
      "title": "Home",
      "href": "#"
    },
    {
      "title": "About",
      "href": "about"
    },
    {
      "title": "History",
      "href": "about/history"
    },
    {
      "title": "Contact",
      "href": "contact"
    },
    {
      "title": "Other things - in a list. (Click here)",
      "submenu": [
        {
          "header": "Sample Header"
        },
        {
          "title": "Some Link",
          "href": "some/place"
        },
        {
          "title": "Another Link",
          "href": "some/other/place"
        },
        {
          "divider": "true"
        },
        {
          "header": "Header 2"
        },
        {
          "title": "Again...a link.",
          "href": "errrr"
        },
        {
          "title": "Nest Parent",
          "submenu": [
            {
              "title": "nested again",
              "href": "nested/again"
            },
            {
              "title": "me too",
              "href": "sample/place"
            }
          ]
        }
      ]
    }
  ];
});

更新嵌套的下拉列表:

住在这里的演示(点击进入)。

Update for nested dropdown:

Live demo here (click).

.dropdown-menu .dropdown-menu {
  margin: 0;
  left: 100%;
  top: -5px;
}

.dropdown-menu li:hover .dropdown-menu {
  display: block;
}

这篇关于AngularJS多级下拉菜单从递归指令生成的菜单结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆