Проверьте, является ли event.target дочерним элементом угловой директивы (элемента)

Я сделал пользовательскую (ul li) выпадающую директиву.

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

Большая часть этого достигается с помощью следующего кода (Закрывающая и открывающая части).

scope.closeDropDown = function () {
    scope.isOpened = false;
    $document.unbind('click');
};

//The part for opening and closing is pressed
scope.openDropDown = function () {
    if (scope.isOpened) {
        //The dropdown is already opened, close it
        scope.closeDropDown();
    } else {
        //Open the dropdown, and add an event handler to the document
        scope.isOpened = true;

        $document.bind('click', function (evt) {
            var target = $(evt.target);
            // Check if the document clicked element is a child of the directive
            // ATTENTION HERE
            if (!target.parents('dropdown').length) {
                //Target is not a child element, close the dropdown
                scope.closeDropDown();
                scope.$apply();
            }
        });
    }
};

Посмотрите внимательно на часть ВНИМАНИЕ ЗДЕСЬ.
Здесь я установил прослушиватель событий на всю страницу. Использование этого дает мне следующую проблему:

Пример: при наличии нескольких раскрывающихся списков (как пример A и B).

  • Открыть раскрывающийся список А
    • раскрывающийся список А открывается правильно
  • Открыть раскрывающийся список B
    • раскрывающийся список B открывается правильно
    • dropdown A получает событие документа и говорит, что нажатый элемент является дочерним для выпадающей директивы (что правильно)
    • выпадающий список А не закрывается (но я хочу, чтобы он закрылся!)

Как я могу проверить, является ли event.target дочерним элементом angular.element?
Как и сейчас, я проверяю только, является ли event.target дочерним элементом выпадающей директивы (это эффективно только при использовании 1 выпадающей директивы)!

1 ответ

Решение

По просьбе Zia Ul Rehman Mughal я обновлю вопрос ответом, который я использовал в своей собственной раскрывающейся директиве.


Часть, в которой я допустил ошибку, заключалась в том, чтобы добавить прослушиватель щелчков при открытии раскрывающегося списка и снова удалить его при закрытии. Это неправильно!

Вы должны добавить слушателей, когда объект создан, и удалить их снова, когда объект разрушается (с угловым $destroy событие.

Чтобы проверить, является ли выбранная цель дочерним элементом элемента, вы можете использовать length атрибут $element.find(event.target)

function closeDropDown() {
    $scope.opened = false;
}

function handleClickEvent(event) {
    /* When the clicked element is not a child of the element and
       the dropdown is openend, close the dropdown. */
    if ($element.find(event.target).length === 0 && $scope.opened) {
        closeDropDown();
        /* Trigger new digest cycle */
        $scope.$apply();
    }
};

function setListeners() {
    /* Bind click event to the document, close the dropDown if clicked
       elsewhere on the page. */
    var clickHandler = handleClickEvent;
    $document.bind('click', clickHandler);

    /*  Remove the used event handlers when destroying the object */
    $scope.$on('$destroy', function () {
        $document.unbind('click', clickHandler);
    });
}
Другие вопросы по тегам