Подтвердить что ты не робот

Как предотвратить выпадение angular -bootstrap после закрытия (Unbind Event, связанное с директивой)

Я использую 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?

4b9b3361

Ответ 1

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

<ul class="dropdown-menu" ng-click="$event.stopPropagation()">

Ответ 2

Для тех, кто использует Angular UI-Bootstrap 0.13.0 или более позднюю версию, вот более чистый способ, который указывается в документации UI-Bootstrap.

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

  • всегда - (по умолчанию) автоматически закрывает выпадающий список, если любой из его элементов.

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

  • отключено - отключает автоматическое закрытие. Затем вы можете управлять открыть/закрыть статус раскрывающегося меню вручную, используя is-open. пожалуйста обратите внимание, что выпадающее меню все равно будет закрыто, если щелкнуть переключатель, клавиша esc нажата или откроется другое раскрывающееся меню. Выпадающий список больше не закрываются на события $locationChangeSuccess.

Вот ссылка на документацию: https://angular-ui.github.io/bootstrap/#/dropdown

Ответ 3

Это еще один хак, но вы можете добавить директиву, чтобы остановить распространение события переключения. Например, что-то вроде этого работало для моего конкретного случая использования:

<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();
            });
        }
    };
});

Пример Plunker здесь

Ответ 4

Это грубый способ переопределить его. Вам нужно управлять атрибутом 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) для постоянного решения.

Ответ 5

Это еще более грубый способ переопределить его, основываясь на ответе Роба Джейкобса, за исключением того, что он предотвращает уродливое мерцание ulilcht:

    $scope.toggled = function (open) {
        $scope.open = true;
        var child = $scope.$$childHead;
        while (child) {
            if (child.focusToggleElement) {
                child.isOpen = true;
                break;
            }
            child = child.$$nextSibling;
        }
    };

Ответ 6

Вы также можете использовать это решение: https://gist.github.com/Xspirits/684beb66e2499c3ff0e5 Дает вам немного больше контроля над выпадающим списком, если это когда-либо понадобится.

Ответ 7

Вы можете украсить директивы.

Таким образом, вам не нужно прикасаться к исходному коду, и вы можете сохранить исходное поведение.

Вы можете поместить кнопку закрытия в раскрывающемся меню

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;
    }
}

Ответ 8

Вот как выглядит код с использованием одобренного метода 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>

Ответ 9

Вы можете остановить всплывание события в DOM Tree под углом 2 и выше, добавив приведенный ниже код.