2014-10-14 4 views
2

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

В моем браузере консоли есть я Нет ошибки.

Почему вы не можете щелкнуть выпадающее меню?

http://plnkr.co/edit/WHswYfce44W6WWZR1T7y?p=preview

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope) { 

    var schoolclassCodeColors = [ 
    {background:'blue'}, 

    {background:'red'} 
    ]; 

    var newSubject = "test"; 
    var newSchoolclass = "11"; 
    var newSchoolclassIdentifier = "xb"; 

    $scope.activeStep = {}; 
    $scope.activeStep.schoolclassCodeColors = schoolclassCodeColors; 
    $scope.activeStep.schoolclassCodeColorsIsOpen = false; 

    $scope.activeStep.selectedSchoolclassCodeColor = $scope.activeStep.schoolclassCodeColors[0]; 

    $scope.activeStep.schoolclassCode = function() { 
     return newSubject + newSchoolclass + newSchoolclassIdentifier; 
    }; 

    $scope.activeStep.setSchoolclassCodeColor = function(color){ 
    $scope.activeStep.selectedSchoolclassCodeColor = color; 
    this.schoolclassCodeColorsIsOpen = false; 

}; 
}); 

app 
.constant('dropdownConfig', { 
    openClass: 'open' 
}) 

.service('dropdownService', ['$document', function($document) { 
    var openScope = null; 

    this.open = function(dropdownScope) { 
    if (!openScope) { 
     $document.bind('click', closeDropdown); 
     $document.bind('keydown', escapeKeyBind); 
    } 

    if (openScope && openScope !== dropdownScope) { 
     openScope.isOpen = false; 
    } 

    openScope = dropdownScope; 
    }; 

    this.close = function(dropdownScope) { 
    if (openScope === dropdownScope) { 
     openScope = null; 
     $document.unbind('click', closeDropdown); 
     $document.unbind('keydown', escapeKeyBind); 
    } 
    }; 

    var closeDropdown = function(evt) { 
    // This method may still be called during the same mouse event that 
    // unbound this event handler. So check openScope before proceeding. 
    if (!openScope) { return; } 

    var toggleElement = openScope.getToggleElement(); 
    if (evt && toggleElement && toggleElement[0].contains(evt.target)) { 
     return; 
    } 

    openScope.$apply(function() { 
     openScope.isOpen = false; 
    }); 
    }; 

    var escapeKeyBind = function(evt) { 
    if (evt.which === 27) { 
     openScope.focusToggleElement(); 
     closeDropdown(); 
    } 
    }; 
}]) 

.controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate) { 
    var self = this, 
     scope = $scope.$new(), // create a child scope so we are not polluting original one 
     openClass = dropdownConfig.openClass, 
     getIsOpen, 
     setIsOpen = angular.noop, 
     toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop; 

    this.init = function(element) { 
    self.$element = element; 

    if ($attrs.isOpen) { 
     getIsOpen = $parse($attrs.isOpen); 
     setIsOpen = getIsOpen.assign; 

     $scope.$watch(getIsOpen, function(value) { 
     scope.isOpen = !!value; 
     }); 
    } 
    }; 

    this.toggle = function(open) { 
    return scope.isOpen = arguments.length ? !!open : !scope.isOpen; 
    }; 

    // Allow other directives to watch status 
    this.isOpen = function() { 
    return scope.isOpen; 
    }; 

    scope.getToggleElement = function() { 
    return self.toggleElement; 
    }; 

    scope.focusToggleElement = function() { 
    if (self.toggleElement) { 
     self.toggleElement[0].focus(); 
    } 
    }; 

    scope.$watch('isOpen', function(isOpen, wasOpen) { 
    $animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass); 

    if (isOpen) { 
     scope.focusToggleElement(); 
     dropdownService.open(scope); 
    } else { 
     dropdownService.close(scope); 
    } 

    setIsOpen($scope, isOpen); 
    if (angular.isDefined(isOpen) && isOpen !== wasOpen) { 
     toggleInvoker($scope, { open: !!isOpen }); 
    } 
    }); 

    $scope.$on('$locationChangeSuccess', function() { 
    scope.isOpen = false; 
    }); 

    $scope.$on('$destroy', function() { 
    scope.$destroy(); 
    }); 
}]) 

.directive('dropdown', function() { 
    return { 
    controller: 'DropdownController', 
    link: function(scope, element, attrs, dropdownCtrl) { 
     dropdownCtrl.init(element); 
    } 
    }; 
}) 

.directive('dropdownToggle', function() { 
    return { 
    require: '?^dropdown', 
    link: function(scope, element, attrs, dropdownCtrl) { 
     if (!dropdownCtrl) { 
     return; 
     } 

     dropdownCtrl.toggleElement = element; 

     var toggleDropdown = function(event) { 
     event.preventDefault(); 

     if (!element.hasClass('disabled') && !attrs.disabled) { 
      scope.$apply(function() { 
      dropdownCtrl.toggle(); 
      }); 
     } 
     }; 

     element.bind('click', toggleDropdown); 

     // WAI-ARIA 
     element.attr({ 'aria-haspopup': true, 'aria-expanded': false }); 
     scope.$watch(dropdownCtrl.isOpen, function(isOpen) { 
     element.attr('aria-expanded', !!isOpen); 
     }); 

     scope.$on('$destroy', function() { 
     element.unbind('click', toggleDropdown); 
     }); 
    } 
    }; 
}); 

HTML

</head> 

    <body ng-controller="MainCtrl"> 
    <div class="col-md-6"> 
     <div class="btn-group" dropdown is-open="activeStep.schoolclassCodeColorsIsOpen"> 
      <button type="button" ng-style="{{activeStep.selectedSchoolclassCodeColor}}" 
        class="btn btn-primary dropdown-toggle" ng-disabled="disabled"> 
       {{activeStep.schoolclassCode()}} <span class="caret"></span> 
      </button> 
      <ul class="dropdown-menu" role="menu"> 
       <li ng-repeat="color in activeStep.schoolclassCodeColors"> 
        <a ng-style="{{color}}" 
        ng-click="activeStep.setSchoolclassCodeColor(color)">{{activeStep.schoolclassCode()}}</a> 
       </li> 
      </ul> 
     </div> 
    </div> 
    </body> 

</html> 

ответ

1

Для того, чтобы использовать dropdownToggle директивы внутри атрибута class, необходимо определить restrict разрешения от директивы для включения C (C девахи). Например:

.directive('dropdownToggle', function() { 
    return { 
    restrict: 'AEC', 
    require: '?^dropdown', 
    // ... 
}); 

От Angular's documentation:

Ограничить параметр обычно устанавливается:

'A' - только матчи имени атрибута

'E' - соответствует только элемент наименование

'C' - только соответствует названию класса

Demo

+0

Почему имеет оригинальный источник: https://github.com/angular-ui/bootstrap/blob/master/src/dropdown/dropdown. js NOT AEC ограничивает набор/используется ??? – HelloWorld

+0

Возможно, потому, что они не хотят, чтобы мы использовали его в атрибуте 'class' (обычно' class' предназначен для стилей, а не для «функциональных возможностей»). Значением по умолчанию является '' EA'' (** E ** lements и ** A ** ttributes), поэтому вы должны иметь возможность использовать директиву в обоих режимах. – bmleite

+0

Хорошо, проблема в том, что я использовал директиву не так, как автор этого хочет! Я теперь поставил директиву на a-tag, тогда он работает без ограничения AEC! Но есть визуальная ошибка, теперь директива находится на a-tag, круговые углы с правой стороны исчезли! – HelloWorld

0
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.js"></script> 
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" /> 

<script data-require="[email protected]" src="https://code.angularjs.org/1.2.25/angular.js" data-semver="1.2.25"></script> 
<script src="app.js"></script> 

<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> 

вам нужно добавить bootstrap.min.js и jquery.js JavaScript файлы, а также вам нужно добавить, data-toggle="dropdown" атрибут button, как показано ниже

<button type="button" ng-style="{{activeStep.selectedSchoolclassCodeColor}}" 
       class="btn btn-primary dropdown-toggle" ng-disabled="disabled" data-toggle="dropdown">  

вот plunker demo

0

Это кажется ужасно много кода для того, что вы пытаетесь сделать. Я не могу сказать, является ли ответ ниже тем, что вы ищете. Я предполагаю, что вы пытаетесь создать угловую версию переключения bootstrap.

Похоже, вы неправильно поняли, что require и атрибут директивы директивы controller. Я думаю, что угловые документы, вероятно, являются источником этой путаницы, к сожалению:

Когда директива требует контроллера, он получает этот контроллер в качестве четвертого аргумента своей функции связи.

Это говорит о том, что директива требует контроллера, но это на самом деле так, что директива требует другой директивы. И что необходимый контроллер директивы передается функции связывания.

Атрибут контроллера не должен быть строкой (controller: 'DropdownController',), но должен быть функцией-конструктором для контроллера. Поэтому я думаю, что вы можете решить свою проблему, переместив DropdownController в директиву.

Для примера что-то подобное (но простой), вы можете see this answer and the plnkr.