指令中的子菜单没有'不起作用

Sub menu within directive doesn't work

本文关键字:不起作用 菜单 指令      更新时间:2023-09-26

我有一个多层菜单,可以很好地用作硬编码的html。一旦我将子菜单项移动到angularJs指令(导航下拉菜单)中,它就不再正常工作,而是在我单击子菜单项时关闭父菜单。除了AngularJS以外的所有东西都应该忽略的一些AngularJS类和属性之外,生成的HTML是相同的。

请参阅此处的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;
      }
  }
});

我正在使用引导程序子菜单项目:http://vsn4ik.github.io/bootstrap-submenu/

将行为应用于子菜单的代码行是:

$('[data-submenu]').submenupicker();

问题是,这行代码是在子菜单存在之前执行的,因此永远不会应用该行为。修复方法是在将子菜单项(departments)添加到作用域后,将此代码封装在$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);
  });