Ответ 1
Я решил это, добавив следующее в мое раскрывающееся меню. Это предотвратит закрытие папок, если вы не нажмете на тег, который его открывает.
<ul class="dropdown-menu" ng-click="$event.stopPropagation()">
Я использую Angular -Bootstrap Dropdown. Я хочу, чтобы он не закрывался, пока пользователь не закрыл его намеренно.
Состояние по умолчанию: раскрывающаяся папка закрывается при нажатии в документе.
Я определил соответствующие строки кода: (строка 12, dropdown.js)
this.open = function( dropdownScope ) {
if ( !openScope ) {
$document.bind('click', closeDropdown); // line to unbind
$document.bind('keydown', escapeKeyBind);
}
}
Вы можете найти полный код здесь: Ссылка на Github
Я не хочу менять исходные источники Angular -bootstrap, чтобы мой проект был открыт для обновлений.
Мой вопрос:
Как я могу отвязать событие, связанное директивой с документом в контроллере Angular?
Я решил это, добавив следующее в мое раскрывающееся меню. Это предотвратит закрытие папок, если вы не нажмете на тег, который его открывает.
<ul class="dropdown-menu" ng-click="$event.stopPropagation()">
Для тех, кто использует Angular UI-Bootstrap 0.13.0 или более позднюю версию, вот более чистый способ, который указывается в документации UI-Bootstrap.
По умолчанию выпадающее меню автоматически закрывается, если щелкнуть любой из его элементов, вы можете изменить это поведение, установив опцию автоматического закрытия следующим образом:
всегда - (по умолчанию) автоматически закрывает выпадающий список, если любой из его элементов.
outsideClick - автоматически закрывает раскрывающийся список только тогда, когда пользователь нажимает любой элемент вне раскрывающегося списка.
отключено - отключает автоматическое закрытие. Затем вы можете управлять открыть/закрыть статус раскрывающегося меню вручную, используя is-open. пожалуйста обратите внимание, что выпадающее меню все равно будет закрыто, если щелкнуть переключатель, клавиша esc нажата или откроется другое раскрывающееся меню. Выпадающий список больше не закрываются на события $locationChangeSuccess.
Вот ссылка на документацию: https://angular-ui.github.io/bootstrap/#/dropdown
Это еще один хак, но вы можете добавить директиву, чтобы остановить распространение события переключения. Например, что-то вроде этого работало для моего конкретного случая использования:
<div>
<div class="btn-group" dropdown is-open="status.isopen" ng-controller="DropDownCtrl">
<button type="button" class="btn btn-primary dropdown-toggle" ng-disabled="disabled">
Button dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li ng-click="goToPage('Action')">Action</li>
<li disable-auto-close>Don't Dismiss</li>
<li ng-click="goToPage('SomethingElse')">Something else here</li>
</ul>
</div>
Добавление этой директивы в элемент должно отключить поведение автоматического закрытия:
angular.module('plunker', ['ui.bootstrap'])
.controller('DropDownCtrl', ['$scope', '$location',
function($scope, $location) {
// Controller logic here
$scope.goToPage = function(page) {
console.log("Going to " + page + ". Dropdown should close");
$location.path(page);
};
}])
.directive('disableAutoClose', function() {
// directive for disabling the default
// close on 'click' behavior
return {
link: function($scope, $element) {
$element.on('click', function($event) {
console.log("Dropdown should not close");
$event.stopPropagation();
});
}
};
});
Это грубый способ переопределить его. Вам нужно управлять атрибутом is-open вручную и захватить событие on-toggle, например:
<div class="btn-group" dropdown is-open="ctrl.isOpen" on-toggle="toggled(open)">
<button type="button" class="btn btn-primary dropdown-toggle">
Button dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</div>
Контроллер:
$scope.toggled = function (open) {
$timeout(function () {
$scope.ctrl.isOpen = true;
});
};
Я бы попросил свойство для константы dropdownConfig (что-то вроде autoClose) для постоянного решения.
Это еще более грубый способ переопределить его, основываясь на ответе Роба Джейкобса, за исключением того, что он предотвращает уродливое мерцание ulilcht:
$scope.toggled = function (open) {
$scope.open = true;
var child = $scope.$$childHead;
while (child) {
if (child.focusToggleElement) {
child.isOpen = true;
break;
}
child = child.$$nextSibling;
}
};
Вы также можете использовать это решение: https://gist.github.com/Xspirits/684beb66e2499c3ff0e5 Дает вам немного больше контроля над выпадающим списком, если это когда-либо понадобится.
Вы можете украсить директивы.
Таким образом, вам не нужно прикасаться к исходному коду, и вы можете сохранить исходное поведение.
Вы можете поместить кнопку закрытия в раскрывающемся меню
HTML
<div class="dropdown-menu keep-dropdown-open-on-click" role="menu">
<i class="icon-close close-dropdown-on-click"></i>
</div>
JS
angular.module('app').config(uiDropdownMenuDecorate);
uiDropdownMenuDecorate.$inject = ['$provide'];
function uiDropdownMenuDecorate($provide) {
$provide.decorator('dropdownMenuDirective', uiDropdownMenuDecorator);
uiDropdownMenuDecorator.$inject = ['$delegate'];
function uiDropdownMenuDecorator($delegate) {
var directive = $delegate[0];
var link = directive.link;
directive.compile = function () {
return function (scope, elem, attrs, ctrl) {
link.apply(this, [scope, elem, attrs, ctrl]);
elem.click(function (e) {
if (elem.hasClass('keep-dropdown-open-on-click') && !angular.element(e.target).hasClass('close-dropdown-on-click')) {
e.stopPropagation();
}
});
};
};
return $delegate;
}
}
Вот как выглядит код с использованием одобренного метода angular -bootstrap auto-close. Обратите внимание, что атрибут auto-close находится в верхней части <div>
.
<div class="btn-group" uib-dropdown auto-close="disabled">
<button id="single-button" type="button" class="btn btn-primary" uib-dropdown-toggle>
Button dropdown <span class="caret"></span>
</button>
<ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="single-button">
<textarea class="form-control" ng-model="description" rows="4" placeholder="Description"></textarea>
</ul>
</div>
Вы можете остановить всплывание события в DOM Tree под углом 2 и выше, добавив приведенный ниже код.