我正在使用Angular-Bootstrap Dropdown。我想阻止它关闭点击,直到用户故意关闭它。
默认状态为:单击文档中的某个位置时,Dropdown关闭。
我确定了相关的代码行:(第12行,dropdown.js)
this.open = function( dropdownScope ) {
if ( !openScope ) {
$document.bind('click', closeDropdown); // line to unbind
$document.bind('keydown', escapeKeyBind);
}
}
您可以在此处找到完整代码:Link to Github
我不想更改angular-bootstrap的原始来源以保持我的项目更新。
我的问题:
如何将指令绑定的事件解除绑定到角度控制器中的文档?
答案 0 :(得分:136)
我通过在下拉菜单中添加以下内容来解决这个问题。这可以防止关闭下拉,除非您单击打开它的标记
<ul class="dropdown-menu" ng-click="$event.stopPropagation()">
答案 1 :(得分:25)
对于那些使用Angular UI-Bootstrap 0.13.0或更高版本的人来说,这是在UI-Bootstrap文档中说明的更清晰的方式。
默认情况下,如果单击任何元素,下拉列表将自动关闭,您可以通过设置自动关闭选项来更改此行为,如下所示:
始终 - (默认)自动关闭任何下拉列表 单击元素。
outsideClick - 仅在用户时自动关闭下拉列表 单击下拉列表外的任何元素。
已禁用 - 禁用自动关闭。然后你可以控制 通过使用is-open手动打开/关闭下拉列表。请 请注意,如果单击切换,下拉列表仍会关闭, 按下esc键或打开另一个下拉列表。下拉列表将会 不再关闭$ locationChangeSuccess事件。
答案 2 :(得分:3)
这是另一个hack,但你可以添加一个指令来阻止toggle事件传播。例如,像我这样的特定用例:
<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();
});
}
};
});
答案 3 :(得分:0)
这是一种粗暴的方式。您需要手动控制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)上寻求一个永久解决方案的属性。
答案 4 :(得分:0)
根据Rob Jacobs的回答,这是一种更为粗暴的覆盖方式,除了它可以防止丑陋的闪烁ulilcht发表评论:
$scope.toggled = function (open) {
$scope.open = true;
var child = $scope.$$childHead;
while (child) {
if (child.focusToggleElement) {
child.isOpen = true;
break;
}
child = child.$$nextSibling;
}
};
答案 5 :(得分:0)
您也可以使用此解决方案:https://gist.github.com/Xspirits/684beb66e2499c3ff0e5 如果需要,可以让您更多地控制下拉列表。
答案 6 :(得分:0)
您可以修饰指令。
通过这种方式,您不必触摸原始代码,您可以保留原始行为。
您可以在下拉列表中放置关闭按钮
<强> 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;
}
}
答案 7 :(得分:0)
以下是使用经过批准的angular-bootstrap自动关闭方法的代码。请注意,自动关闭属性位于顶部<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>
答案 8 :(得分:0)
您可以通过添加事件传播来阻止事件在Ang Tree 2和更高版本的DOM树中冒泡。 例如:(click)=“ $ event.stopPropagation()”