Javascript AngularJS多级下拉菜单,用于递归指令生成的菜单结构
我这里有一点腌菜。 我必须从Web服务调用中获取多级导航菜单 因为我的导航菜单可以有无限多的子菜单,所以我不得不使用递归指令来构建父/子导航结构。 现在我正试图找出如何将其转换为功能性的dropmenu结构。 我在看angularui的bootstrap,他们有一个 下拉切换,它有一些基本的下拉菜单功能,但是 我使用了一个递归指令,我的菜单结构已经有了angularjs生成的css 与之相关的课程。angularjs引导下拉菜单 css类与我的angularjs生成的类不同…看Javascript AngularJS多级下拉菜单,用于递归指令生成的菜单结构,javascript,angularjs,angularjs-directive,angularjs-bootstrap,Javascript,Angularjs,Angularjs Directive,Angularjs Bootstrap,我这里有一点腌菜。 我必须从Web服务调用中获取多级导航菜单 因为我的导航菜单可以有无限多的子菜单,所以我不得不使用递归指令来构建父/子导航结构。 现在我正试图找出如何将其转换为功能性的dropmenu结构。 我在看angularui的bootstrap,他们有一个 下拉切换,它有一些基本的下拉菜单功能,但是 我使用了一个递归指令,我的菜单结构已经有了angularjs生成的css 与之相关的课程。angularjs引导下拉菜单 css类与我的angularjs生成的类不同…看 <ul&g
<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 > 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>
它是从官方的引导css文件中获得的。
不知道为什么它不可见。
不确定它是否有用,但这里是ul之后下一个li元素的css
*, *: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;
}
请记住,当我添加angularui引导所需的css标记时,您必须转到plunker页面才能看到更新的代码。
要查看不可见的导航元素,您需要像Firebug这样的东西来查看DOM
下面是我的更新中的一些html最终输出(来自DOM)的示例,用于尝试使用angularui引导css类
...
<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引导库不工作的原因是“recursive list item..”元素是“li”元素的子元素,而“a”元素的父元素。我的直觉正确吗?这就是我使用的,它有很多额外的功能,非常好用。 查看用法
$scope.menu
,以及展开下拉列表时会发生什么-您可以放入标题、分隔符,甚至附加单击函数。请注意,您可以根据需要嵌套任意多个ul
,尽管切换确实有效,但它是无用的,因为单击打开子菜单将隐藏其父菜单。据我所知,如果您想在菜单中进行更深的嵌套,您需要创建自己的javascript处理程序或使用鼠标悬停自定义css
不理解课程为什么重要。一个元素可以有许多类。此外,您还可以修改甚至不使用ui DropwDown中的CSS。我也遇到过类似的问题,并用这个方法解决了这个问题:它可以帮助您创建角度引导结构。当从服务中刷新时,我遇到了项目重复的问题,但这是一个新问题。我根据文档添加了适当的类,现在整个过程都不可见了。元素结构在DOM(firebug)中,但在导航结构中看不到任何类别。我添加了“ui.bootstrap”作为控制器模块的依赖项,并将ui-bootstrap-tpls-0.7.0.min.js添加到我的index.html页面,我还添加了bootstrap.css,甚至根据文档添加了额外的css行。有什么想法吗?Charlietfl,我创建了一个单独的Plunker项目,该项目只做了一些更改,将css类添加到必要的html中。好的,我看了你的演示。单击打开子菜单时,父菜单确实会关闭。似乎库应该为子菜单处理这个问题…@thebravedave是的,不幸的是,我几乎完全肯定它不是有意的。有一点需要考虑的是,嵌套的子菜单是一种糟糕的做法。在一个级别之后,这对用户来说是一种压力(我还要点击多少个呢?)。不过,你可以在这里轻松地创建自己的功能。当然,你最好也有一些悬停功能。
*, *: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;
}
...
<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>
...
<nav>
<div menu="menu"></div> <!-- the element here doesn't matter -->
</nav>
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"
}
]
}
]
}
];
});
.dropdown-menu .dropdown-menu {
margin: 0;
left: 100%;
top: -5px;
}
.dropdown-menu li:hover .dropdown-menu {
display: block;
}