1

Что происходит?Почему мои индивидуальные директивы выпадающего списка?

Все работает и правильно заполняется из того, что я могу сказать. Выпадающим является только то, что неправильно. По какой-то причине он не будет запускать и отображать все его подменю/разделители.

app.directives.js

angular.module('mb.essentials', []) 
.directive('mbAttribute', function ($log) { 
    return { 
     restrict: 'A', 
     scope: { 
      mbAttribute: '=' 
     }, 
     link: function(scope, element, attrs) { 
      if (angular.isUndefined(scope.mbAttribute)) { 
       $log.error(
        'You must specify at least one attribute, condition pair!\n' + 
        'Eg. mb-attribute="{\'alert-warning\': alert.alertType}"'); 
      } 

      $.each(scope.mbAttribute, function (key, value) { 
       scope.$watch(function() { 
        return value; 
       }, 
       function() { 
        if (value) { 
         element.attr(key, ''); 
        } else { 
         element.removeAttr(key, ''); 
        } 
       }); 
      }); 
     } 
    }; 
}) 
.directive('mbNavbar', function() { 
    return { 
     restrict: 'AE', 
     require: '^dropdown', 
     transclude: true, 
     scope: { 
      brand: '=', 
      menus: '=', 
      affixed: '=', 
      inverse: '=', 
      search: '=', 
      searchFn: '&', 
      navFn: '&' 
     }, 
     controller: function ($scope, $element, $attrs, $sce) { 
      $scope.isCollapsed = true; 

      $scope.defaults = { 
       brand: '<span class="glyphicon glyphicon-certificate"></span>', 
       menus: [], 
       search: { 
        show: false 
       } 
      }; // end defaults 

      if (angular.isUndefined($attrs.navFn)) { 
       $scope.navfn = function (action) { 
        if (angular.isObject(action)) 
         $scope.$emit('nav.menu', action); 
        else 
         $scope.$emit('nav.menu', {'action': action}); 
       } 
      }; 

      if (angular.isUndefined($attrs.searchFn)) { 
       $scope.searchFn = function() { 
        $scope.$emit('nav.search.execute'); 
       } 
      }; 

      $scope.trustedBrand = angular.isDefined($attrs.brand) ? $sce.trustAsHtml($scope.brand) : $sce.trustAsHtml($scope.defaults.brand); 
      $scope.hasMenus = function() { 
       return angular.isDefined($scope.menus); 
      }; 

      $scope.hasDropdownMenu = function (menu) { 
       return (angular.isDefined(menu.menu) && angular.isArray(menu.menu)); 
      }; 

      $scope.isDivider = function (item) { 
       return (angular.isDefined(item.divider) && angular.equals(item.divider, true)); 
      } 

      $scope.navAction = function (action) { 
       $scope.navFn({'action': action}); 
      }; 
     }, 
     template: 
     '<nav class="navbar" ng-class="{\'navbar-inverse\': inverse,\'navbar-default\': !inverse,\'navbar-fixed-top\': affixed == \'top\',\'navbar-fixed-bottom\': affixed == \'bottom\'}" role="navigation">' + 
      '<div class="container-fluid">' + 
       '<div class="navbar-header">' + 
        '<button type="button" class="navbar-toggle" ng-click="isCollapsed = !isCollapsed">' + 
         '<span class="sr-only">Toggle Navigation</span>' + 
         '<span class="icon-bar"></span>' + 
         '<span class="icon-bar"></span>' + 
         '<span class="icon-bar"></span>' + 
        '</button>' + 
        '<a class="navbar-brand" ng-bind-html="trustedBrand"></a>' + 
       '</div>' + 
       '<div collapse="isCollapsed" class="collapse navbar-collapse">' + 
        '<ul class="nav navbar-nav" ng-if="hasMenus()">' + 
         '<li ng-repeat="menu in menus" mb-attribute="{\'dropdown\': hasDropdownMenu(menu)}">' + 
          '<a ng-if="!hasDropdownMenu(menu)" ng-click="navAction(menu.action)">{{menu.title}}</a>' + 
          '<a ng-if="hasDropdownMenu(menu)" class="dropdown-toggle" dropdown-toggle>' + 
           '{{menu.title}} <b class="caret"></b>' + 
          '</a>' + 
          '<ul ng-if="hasDropdownMenu(menu)" class="dropdown-menu">' + 
           '<li ng-repeat="item in menu.menu" ng-class="{\'nav-divider\': isDivider(item)}">' + 
            '<a ng-if="!isDivider(item)" ng-click="navAction(item.action)">{{item.title}}</a>' + 
           '</li>' + 
          '</ul>' + 
         '</li>' + 
        '</ul>' + 
        '<form ng-if="search.show" class="navbar-form navbar-right" role="search">' + 
         '<div class="form-group">' + 
          '<div class="input-group">' + 
           '<input type="text" class="form-control" placeholder="Search" ng-model="search.terms" />' + 
           '<span class="input-group-btn">' + 
            '<button class="btn btn-default" type="button">' + 
             '<span class="glyphicon glyphicon-search"></span>' + 
            '</button>' + 
           '</span>' + 
          '</div>' + 
         '</div>' + 
        '</form>' + 
       '</div>' + 
      '</div>' + 
     '</nav>' 
    }; 
}); 

Plnkr

+0

Это не то, что считается *** минимальным ***, проверяемым примером. Предложите создать демоверсию plunker – charlietfl

+0

Я создал демонстрацию plunker и только сохранил фрагмент кода директив. Любая помощь приветствуется. – nickwoodward

+0

- все зависимости включены для navbar? Кажется, требуется требование для директивного контроллера 'dropdown', но я не вижу этой директивы ..' require: '^ dropdown', ' – charlietfl

ответ

1

Этот вопрос

В основном угловой компилирует DOM, то директива МБ-атрибут добавляет директиву выпадающий , По сути Угловой и UI Bootstrap не имеют представления о том, что директива даже существует.

«Решение»

Я положил это в кавычки, потому что это не совсем решение.

Вместо этого условно проверяем, следует ли добавить директиву выпадающего списка. Мы просто добавляем его к каждому элементу независимо от того, есть ли его раскрывающееся меню.

Причина, по которой это работает в этом случае, заключается в том, что директива выпадающего списка UI Bootstraps требует, чтобы она была сопряжена с выпадающим меню, а также выпадающим меню для правильной работы.

angular.directives.js

angular.module('mb.essentials', []) 
.directive('mbNavbar', function() { 
    return { 
     restrict: 'AE', 
     require: '^dropdown', 
     scope: { 
      brand: '=', 
      menus: '=', 
      affixed: '=', 
      inverse: '=', 
      search: '=', 
      searchFn: '&', 
      navFn: '&' 
     }, 
     controller: function ($scope, $element, $attrs, $sce) { 
      $scope.isCollapsed = true; 

      $scope.defaults = { 
       brand: '<span class="glyphicon glyphicon-certificate"></span>', 
       menus: [], 
       search: { 
        show: false 
       } 
      } // end defaults 

      if (angular.isUndefined($attrs.navFn)) { 
       $scope.navfn = function (action) { 
        if (angular.isObject(action)) 
         $scope.$emit('nav.menu', action); 
        else 
         $scope.$emit('nav.menu', {'action': action}); 
       } 
      } 

      if (angular.isUndefined($attrs.searchFn)) { 
       $scope.searchFn = function() { 
        $scope.$emit('nav.search.execute'); 
       } 
      } 

      $scope.trustedBrand = angular.isDefined($attrs.brand) ? $sce.trustAsHtml($scope.brand) : $sce.trustAsHtml($scope.defaults.brand); 
      $scope.hasMenus = function() { 
       return angular.isDefined($scope.menus); 
      } 

      $scope.hasDropdownMenu = function (menu) { 
       return (angular.isDefined(menu.menu) && angular.isArray(menu.menu)); 
      } 

      $scope.isDivider = function (item) { 
       return (angular.isDefined(item.divider) && angular.equals(item.divider, true)); 
      } 

      $scope.navAction = function (action) { 
       $scope.navFn({'action': action}); 
      } 
     }, 
     template: 
     '<nav class="navbar" ng-class="{\'navbar-inverse\': inverse,\'navbar-default\': !inverse,\'navbar-fixed-top\': affixed == \'top\',\'navbar-fixed-bottom\': affixed == \'bottom\'}" role="navigation">' + 
      '<div class="container-fluid">' + 
       '<div class="navbar-header">' + 
        '<button type="button" class="navbar-toggle" ng-click="isCollapsed = !isCollapsed">' + 
         '<span class="sr-only">Toggle Navigation</span>' + 
         '<span class="icon-bar"></span>' + 
         '<span class="icon-bar"></span>' + 
         '<span class="icon-bar"></span>' + 
        '</button>' + 
        '<a class="navbar-brand" ng-bind-html="trustedBrand"></a>' + 
       '</div>' + 
       '<div collapse="isCollapsed" class="collapse navbar-collapse">' + 
        '<ul class="nav navbar-nav" ng-if="hasMenus()">' + 
         '<li ng-repeat="menu in menus" dropdown>' + 
          '<a ng-if="!hasDropdownMenu(menu)" ng-click="navAction(menu.action)">{{menu.title}}</a>' + 
          '<a ng-if="hasDropdownMenu(menu)" class="dropdown-toggle" dropdown-toggle>' + 
           '{{menu.title}} <b class="caret"></b>' + 
          '</a>' + 
          '<ul ng-if="hasDropdownMenu(menu)" class="dropdown-menu">' + 
           '<li ng-repeat="item in menu.menu" ng-class="{\'nav-divider\': isDivider(item)}">' + 
            '<a ng-if="!isDivider(item)" ng-click="navAction(item.action)">{{item.title}}</a>' + 
           '</li>' + 
          '</ul>' + 
         '</li>' + 
        '</ul>' + 
        '<form ng-if="search.show" class="navbar-form navbar-right" role="search">' + 
         '<div class="form-group">' + 
          '<div class="input-group">' + 
           '<input type="text" class="form-control" placeholder="Search" ng-model="search.terms" />' + 
           '<span class="input-group-btn">' + 
            '<button class="btn btn-default" type="button">' + 
             '<span class="glyphicon glyphicon-search"></span>' + 
            '</button>' + 
           '</span>' + 
          '</div>' + 
         '</div>' + 
        '</form>' + 
       '</div>' + 
      '</div>' + 
     '</nav>' 
    }; 
}); 

Plnkr

Для будущего

Я собираюсь использовать это решение, но я не обозначая это как решение. Я полагаю, что в будущем кто-то придумает реальное решение, тогда я могу отметить его как таковой.

Смежные вопросы