隐藏下拉菜单并使用Angularjs显示子菜单

时间:2017-12-12 17:20:06

标签: angularjs twitter-bootstrap drop-down-menu

点击父下拉菜单中的链接时,我必须显示一个子菜单,显示时,父母应该隐藏,而子项显示

我的尝试:

 <ul class="nav navbar-nav navbar-right " >
        <li class="dropdown">
            <a class="dropdown-toggle" data-toggle="dropdown" title=""></a>
               <ul id="dropdown-menu" class="dropdown-menu" role="menu" ng-hide="showSubMenu">
                  <li> <a href="#"  ng-click="showSubMenu = ! showSubMenu">Hide me and show submenu</a></li>
               </ul>
               <ul  class="dropdown-menu" role="menu"  ng-hide="!showSubMenu">
                  <li><a href="#" ng-click="showSubMenu =!showSubMenu">Hide me and t show back parent</a></li> 
              </ul>
         </li>
   </ul>                                       

更改可见性正在运行,但是不会触发放置事件,我必须再次单击以切换下拉列表,我需要在更改可见性状态后自动完成

1 个答案:

答案 0 :(得分:1)

  

您必须使用Angular sintax

自定义下拉列表

var app = angular.module("app", []);

app.directive('offClick', ['$rootScope', '$parse', function ($rootScope, $parse) {
    var id = 0;
    var listeners = {};
    // add variable to detect touch users moving..
    var touchMove = false;

    // Add event listeners to handle various events. Destop will ignore touch events
    document.addEventListener("touchmove", offClickEventHandler, true);
    document.addEventListener("touchend", offClickEventHandler, true);
    document.addEventListener('click', offClickEventHandler, true);

    function targetInFilter(target, elms) {
        if (!target || !elms) return false;
        var elmsLen = elms.length;
        for (var i = 0; i < elmsLen; ++i) {
            var currentElem = elms[i];
            var containsTarget = false;
            try {
                containsTarget = currentElem.contains(target);
            } catch (e) {
                // If the node is not an Element (e.g., an SVGElement) node.contains() throws Exception in IE,
                // see https://connect.microsoft.com/IE/feedback/details/780874/node-contains-is-incorrect
                // In this case we use compareDocumentPosition() instead.
                if (typeof currentElem.compareDocumentPosition !== 'undefined') {
                    containsTarget = currentElem === target || Boolean(currentElem.compareDocumentPosition(target) & 16);
                }
            }

            if (containsTarget) {
                return true;
            }
        }
        return false;
    }

    function offClickEventHandler(event) {
        // If event is a touchmove adjust touchMove state
        if (event.type === 'touchmove') {
            touchMove = true;
            // And end function
            return false;
        }
        // This will always fire on the touchend after the touchmove runs...
        if (touchMove) {
            // Reset touchmove to false
            touchMove = false;
            // And end function
            return false;
        }
        var target = event.target || event.srcElement;
        angular.forEach(listeners, function (listener, i) {
            if (!(listener.elm.contains(target) || targetInFilter(target, listener.offClickFilter))) {
                $rootScope.$evalAsync(function () {
                    listener.cb(listener.scope, {
                        $event: event
                    });
                })
            }

        });
    }

    return {
        restrict: 'A',
        compile: function ($element, attr) {
            var fn = $parse(attr.offClick);
            return function (scope, element) {
                var elmId = id++;
                var offClickFilter;
                var removeWatcher;

                offClickFilter = document.querySelectorAll(scope.$eval(attr.offClickFilter));

                if (attr.offClickIf) {
                    removeWatcher = $rootScope.$watch(function () {
                        return $parse(attr.offClickIf)(scope);
                    }, function (newVal) {
                        if (newVal) {
                            on();
                        } else if (!newVal) {
                            off();
                        }
                    });
                } else {
                    on();
                }

                attr.$observe('offClickFilter', function (value) {
                    offClickFilter = document.querySelectorAll(scope.$eval(value));
                });

                scope.$on('$destroy', function () {
                    off();
                    if (removeWatcher) {
                        removeWatcher();
                    }
                });

                function on() {
                    listeners[elmId] = {
                        elm: element[0],
                        cb: fn,
                        scope: scope,
                        offClickFilter: offClickFilter
                    };
                }

                function off() {
                    delete listeners[elmId];
                }
            };
        }
    };
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>

<div ng-app="app">

<div class="dropdown" ng-class="{'show': dropdown}" off-click="dropdown=false;secDropdown=false">
  <button class="btn btn-secondary" type="button" ng-click="dropdown = !dropdown" >
    Dropdown button
  </button>
  <div class="dropdown-menu" ng-class="{'show': dropdown && !secDropdown}">
    <a class="dropdown-item" href="#" ng-click="secDropdown = true">Call Hero!</a>
  </div>
  <div class="dropdown-menu" ng-class="{'show': secDropdown}">
    <a class="dropdown-item" href="#">I'm Hero!</a>
    <div class="dropdown-divider"></div>
    <a class="dropdown-item" href="#" ng-click="secDropdown = false">Back</a>
  </div>
</div>

</div>