0

I am defining a directive that builds a menu by interpreting a list of menu entries defined as objects in an array.

The menu opens and displays fine. It's a pop-over menu: it shows up in the foreground above whatever part of the page that it needs to cover. So far, so good.

However, I want to hide the menu as soon as the user clicks outside the menu. For that, I've used answers to this question to build this:

$scope.closeOnClick = function($scope) {
    var $menu = $('#menu-view');
    $(document).on('click', function(event) {
        if (!$(event.target).closest('#menu-view').length) {
            if ($menu.is(":visible")) {
                $scope.hideMenu();
            }
        }
    });
}

hideMenu is a function defined in the controller of a toggle button that controls opening and closing the menu.

This closeOnClick function is defined in that very controller. It is also called there so as to "install" the click handler.

Unfortunately, it seems that the $scope.hideMenu() is ineffective and no errors are reported in the console. I have also tried using Angular events, with broadcast/on but to no avail.

I'm looking for ideas. Thank you.

AbVog
  • 1,435
  • 22
  • 35

2 Answers2

0

I dont see your hideMenu function, but I guess to make your code work you need add $scope.$apply(); after $scope.hideMenu();

But this is non-angular approach, better use something like:

<button ng-click="hideButton=true" ng-if="!hideButton">Button to hide</button>
Petr Averyanov
  • 9,327
  • 3
  • 20
  • 38
0

This is a classical angular issue. The DOM event handler does NOT run within the Angular lifecycle, thats why you need to use $scope.apply. BTW you should use angular.element() instead of plain jquery.

if ($menu.is(":visible")) {
    $scope.apply($scope.hideMenu);
}
Michael
  • 3,085
  • 1
  • 17
  • 15
  • By removing the visibility test, I've established that `$scope.$apply` does the trick. But although the menu is visible and the selector is correct, `$menu.is(":visible")` was returning false, which I don't get... I've ended up using a opened/close boolean (which I was already keeping and using in the scope) to provide that information. Thanks. – AbVog Jan 19 '16 at 13:52