2015-11-13 58 views
0

我有一個多層菜單,它與硬編碼的html一樣正常工作。只要我將子菜單片段移動到一個angularJs指令(nav-dropdown)中,它就不能正常工作,而當我單擊子菜單項時,會關閉父菜單。除了AngularJS以外的其他應該被忽略的AngularJS類和屬性,所產生的HTML是相同的。指令中的子菜單不起作用

在這裏看到的plunkr:http://plnkr.co/edit/YknatvTulTC0FM2fXkSc?p=preview

注意如何在子菜單「下拉」正確的行爲(在點擊打開子菜單)。 動態生成的所有其他子菜單都不起作用。

下拉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

的代碼,適用行爲到子菜單的該生產線是:

$('[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); 
    });