我有一个多层菜单,可以像硬编码的html一样正常工作。一旦我将子菜单片段移动到angularJs指令(nav-dropdown),它就不再正常工作,而是在我点击子菜单项时关闭父菜单。生成的HTML与一些AngularJS类和属性不同,除了AngularJS之外,其他所有内容都应该忽略。
请在此处查看plunkr:http://plnkr.co/edit/YknatvTulTC0FM2fXkSc?p=preview
注意" Dropdown"下的子菜单。行为正确(点击时打开子菜单)。 动态生成的所有其他子菜单都不起作用。
下拉html(有效):
<li class="dropdown open">
<a tabindex="0" data-toggle="dropdown" data-submenu="" aria-expanded="true">
Dropdown<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li class="dropdown-submenu">
<a tabindex="0">Action</a>
<ul class="dropdown-menu">
<li><a tabindex="0">Sub action</a></li>
<li class="dropdown-submenu">
<a tabindex="0">Another sub action</a>
<ul class="dropdown-menu">
<li><a tabindex="0">Sub action</a></li>
<li><a tabindex="0">Another sub action</a></li>
<li><a tabindex="0">Something else here</a></li>
</ul>
</li>
<li><a tabindex="0">Something else here</a></li>
<li class="dropdown-submenu">
<a tabindex="0">Another action</a>
<ul class="dropdown-menu">
<li><a tabindex="0">Sub action</a></li>
<li><a tabindex="0">Another sub action</a></li>
<li><a tabindex="0">Something else here</a></li>
</ul>
</li>
</ul>
</li>
<li class="dropdown-submenu">
<a tabindex="0">Another action</a>
<ul class="dropdown-menu">
<li><a tabindex="0">Sub action</a></li>
<li><a tabindex="0">Another sub action</a></li>
<li><a tabindex="0">Something else here</a></li>
</ul>
</li>
<li><a tabindex="0">Something else here</a></li>
<li class="divider"></li>
<li><a tabindex="0">Separated link</a></li>
</ul>
</li>
angularjs指令的动态html(不起作用):
<li class="dropdown ng-scope ng-isolate-scope open" ng-repeat="department in vm.departments" department="department">
<a tabindex="0" data-toggle="dropdown" data-submenu="" class="ng-binding ng-scope" aria-expanded="true">
Apparel<span class="caret"></span>
</a>
<ul class="dropdown-menu ng-scope">
<li class="dropdown-submenu">
<a tabindex="0">Action</a>
<ul class="dropdown-menu">
<li><a tabindex="0">Sub action</a></li>
<li class="dropdown-submenu">
<a tabindex="0">Another sub action</a>
<ul class="dropdown-menu">
<li><a tabindex="0">Sub action</a></li>
<li><a tabindex="0">Another sub action</a></li>
<li><a tabindex="0">Something else here</a></li>
</ul>
</li>
<li><a tabindex="0">Something else here</a></li>
<li class="dropdown-submenu">
<a tabindex="0">Another action</a>
<ul class="dropdown-menu">
<li><a tabindex="0">Sub action</a></li>
<li><a tabindex="0">Another sub action</a></li>
<li><a tabindex="0">Something else here</a></li>
</ul>
</li>
</ul>
</li>
<li class="dropdown-submenu">
<a tabindex="0">Another action</a>
<ul class="dropdown-menu">
<li><a tabindex="0">Sub action</a></li>
<li><a tabindex="0">Another sub action</a></li>
<li><a tabindex="0">Something else here</a></li>
</ul>
</li>
<li><a tabindex="0">Something else here</a></li>
<li class="divider"></li>
<li><a tabindex="0">Separated link</a></li>
</ul>
</li>
这里是完整的javascript,你可以在plunkr上看到:
// Code goes here
angular.module('myApp', []);
angular.module('myApp').directive('dccNavigation', function (departmentService) {
return {
restrict: 'E',
scope: {
brandName: '@',
brandImage: '@'
},
replace: true,
templateUrl: 'navigation.html',
controllerAs: 'vm',
controller: function($scope, $timeout) {
var vm = this;
vm.departments = [];
vm.brandName = $scope.brandName;
vm.brandImage = $scope.brandImage;
$('[data-submenu]').submenupicker();
departmentService.getDepartments().then(function(success) {
vm.departments = success.data.departments;
});
}
}
});
angular.module('myApp').directive('dccNavDropdown', function ($compile) {
return {
restrict: 'E',
scope: {
department: '=department',
},
replace: true,
templateUrl: 'nav-dropdown.html',
controller: 'navDropdownController',
controllerAs: 'vm',
compile: function (el) {
var contents = el.contents().remove();
var compiled;
return function(scope,el){
if(!compiled)
compiled = $compile(contents);
compiled(scope,function(clone){
el.append(clone);
});
};
}
}
});
angular.module('myApp').controller('navDropdownController', function($scope, departmentService){
var vm = this;
vm.department = $scope.department;
});
angular.module('myApp').factory('departmentService', function($q){
var customNavElements = [];
return {
customNavElements: customNavElements,
getDepartments: function() {
var departments =[
{"id":18245,"name":"Apparel","level":1,"itemCount":5,"children":[
{"id":3509,"name":"Men","level":2,"itemCount":5,"children":[
{"id":18112,"name":"Jackets","level":3,"itemCount":0,"children":[]},
{"id":18113,"name":"Polos","level":3,"itemCount":0,"children":[]},
{"id":18114,"name":"Sweatshirts","level":3,"itemCount":0,"children":[]},
{"id":18115,"name":"T-Shirts","level":3,"itemCount":0,"children":[]},
{"id":18499,"name":"View all","level":3,"itemCount":0,"children":[]}]},
{"id":3510,"name":"Women","level":2,"itemCount":4,"children":
[{"id":18116,"name":"Jackets","level":3,"itemCount":0,"children":[]},
{"id":18118,"name":"Sweatshirts","level":3,"itemCount":0,"children":[]},
{"id":18119,"name":"T-Shirts","level":3,"itemCount":0,"children":[]},
{"id":18500,"name":"View all","level":3,"itemCount":0,"children":[]}]},
{"id":3513,"name":"Hats","level":2,"itemCount":0,"children":[]},
{"id":5023,"name":"Kids","level":2,"itemCount":0,"children":[]},
{"id":18468,"name":"View All","level":2,"itemCount":0,"children":[]}]},
{"id":3514,"name":"Accessories","level":1,"itemCount":7,"children":[
{"id":18120,"name":"Drinkware","level":2,"itemCount":0,"children":[]},
{"id":18121,"name":"Bags","level":2,"itemCount":0,"children":[]},
{"id":18122,"name":"Office","level":2,"itemCount":0,"children":[]},
{"id":18124,"name":"High-end Tech Items","level":2,"itemCount":0,"children":[]},
{"id":18123,"name":"Tradeshow/Giveaways","level":2,"itemCount":0,"children":[]},
{"id":18226,"name":"Misc","level":2,"itemCount":0,"children":[]},
{"id":18411,"name":"View All","level":2,"itemCount":0,"children":[]}]},
{"id":14961,"name":"Monday Night Football","level":1,"itemCount":0,"children":[]},
{"id":3515,"name":"Golf","level":1,"itemCount":3,"children":[
{"id":18125,"name":"Apparel","level":2,"itemCount":0,"children":[]},
{"id":18126,"name":"Accessories","level":2,"itemCount":0,"children":[]},
{"id":18127,"name":"View All","level":2,"itemCount":0,"children":[]}]},
{"id":18080,"name":"Shop by Price","level":1,"itemCount":4,"children":[
{"id":18081,"name":"Under $5.00","level":2,"itemCount":0,"children":[]},
{"id":18082,"name":"$5.00 - $10.00","level":2,"itemCount":0,"children":[]},
{"id":18083,"name":"$10.01 - $25.00","level":2,"itemCount":0,"children":[]},
{"id":18084,"name":"Over $25.00","level":2,"itemCount":0,"children":[]}]},
{"id":3516,"name":"Sales","level":1,"itemCount":8,"children":[
{"id":16927,"name":"Men","level":2,"itemCount":4,"children":[
{"id":18128,"name":"Jacket","level":3,"itemCount":0,"children":[]},
{"id":18129,"name":"Polos","level":3,"itemCount":0,"children":[]},
{"id":18130,"name":"Sweatshirts","level":3,"itemCount":0,"children":[]},
{"id":18131,"name":"T-Shirts","level":3,"itemCount":0,"children":[]}]},
{"id":16928,"name":"Women","level":2,"itemCount":3,"children":[
{"id":18132,"name":"Jackets","level":3,"itemCount":0,"children":[]},
{"id":18134,"name":"Sweatshirts","level":3,"itemCount":0,"children":[]},
{"id":18135,"name":"T-Shirts","level":3,"itemCount":0,"children":[]}]},
{"id":16929,"name":"Kids","level":2,"itemCount":0,"children":[]},
{"id":16930,"name":"Hats","level":2,"itemCount":0,"children":[]},
{"id":16931,"name":"Accessories","level":2,"itemCount":5,"children":[
{"id":18136,"name":"Drinkware","level":3,"itemCount":0,"children":[]},
{"id":18137,"name":"Bags","level":3,"itemCount":0,"children":[]},
{"id":18138,"name":"Office","level":3,"itemCount":0,"children":[]},
{"id":18139,"name":"Tradeshow/Givaways","level":3,"itemCount":0,"children":[]},
{"id":18304,"name":"Misc","level":3,"itemCount":0,"children":[]}]},
{"id":16932,"name":"Golf","level":2,"itemCount":3,"children":[
{"id":18141,"name":"Apparel","level":3,"itemCount":0,"children":[]},
{"id":18142,"name":"Accessories","level":3,"itemCount":0,"children":[]},
{"id":18143,"name":"View All","level":3,"itemCount":0,"children":[]}]},
{"id":16933,"name":"Monday Night Football","level":2,"itemCount":0,"children":[]},
{"id":16934,"name":"View All","level":2,"itemCount":0,"children":[]}]}];
var deferred = $q.defer();
setTimeout(function(){
deferred.resolve({ data: { departments: departments }});
}, 100);
return deferred.promise;
}
}
});
我正在使用bootstrap-submenu项目:http://vsn4ik.github.io/bootstrap-submenu/
答案 0 :(得分:0)
将行为应用于子菜单的代码行是:
$('[data-submenu]').submenupicker();
问题是这行代码是在子菜单存在之前执行的,因此从不应用该行为。修复是在将子菜单项(部门)添加到范围之后将此代码包装在$ timeout函数中。包装它允许完成AngularJS $摘要周期,并在添加子菜单行为之前将所有元素附加到DOM。
工作Plunkr:http://plnkr.co/edit/c8g43JxntmOXgZI0Wo05?p=preview
departmentService.getDepartments().then(function(success) {
vm.departments = success.data.departments;
$timeout(function(){
$('[data-submenu]').submenupicker();
}, 500);
});