一尘不染

单击div的OUTSIDE时不确定如何隐藏div

angularjs

这是该问题的后续问题:具有焦点的AngularJS输入会杀死list的ng-repeat过滤器
基本上,我的代码是使用AngularJS在右侧弹出一个div(抽屉)以过滤事物列表。大多数情况下使用此功能时,UI会被阻止,因此单击该阻止div会关闭抽屉。但是在某些情况下,我们不会阻止用户界面,需要允许用户在抽屉外部单击以取消搜索或选择页面上的其他内容。

我最初的想法是在抽屉打开时附加一个window.onclick处理程序,如果单击除抽屉以外的任何内容,则应关闭抽屉。这就是我将在纯JavaScript应用程序中执行的操作。但是在Angular中,这会有点困难。

这是一个jsfiddle,其中有一个基于@Yoshi的jsBin示例的示例:http
//jsfiddle.net/tpeiffer/kDmn8/

下面是此示例中的相关代码。基本上,如果用户在抽屉外单击,我将调用$ scope.toggleSearch,以便将$ scope.open设置回false。

代码可以正常工作,即使$ scope.open从true变为false,它也不会修改DOM。我确定这与事件的生命周期有关,或者当我修改$
scope(因为它是来自单独的事件)时,它是副本而不是原始副本…

最终的目标将是成为最终可重用性的指令。如果有人能指出正确的方向,那我将不胜感激。

$scope.toggleSearch = function () {

    $scope.open = !$scope.open;

    if ($scope.open) {
        $scope.$window.onclick = function (event) {
            closeSearchWhenClickingElsewhere(event, $scope.toggleSearch);
        };
    } else {
        $scope.$window.onclick = null;
    }
};

function closeSearchWhenClickingElsewhere(event, callbackOnClose) {

    var clickedElement = event.target;
    if (!clickedElement) return;

    var elementClasses = clickedElement.classList;
    var clickedOnSearchDrawer = elementClasses.contains('handle-right') 
        || elementClasses.contains('drawer-right') 
        || (clickedElement.parentElement !== null 
            && clickedElement.parentElement.classList.contains('drawer-right'));
    if (!clickedOnSearchDrawer) {
        callbackOnClose();
    }

}

阅读 249

收藏
2020-07-04

共1个答案

一尘不染

抽屉未关闭,因为click事件发生在摘要周期之外,并且Angular不知道$scope.open已更改。要修复它,您可以在$scope.open设置为false后调用$ scope。$apply(),这将触发摘要周期。

$scope.toggleSearch = function () {
    $scope.open = !$scope.open;
    if ($scope.open) {
        $scope.$window.onclick = function (event) {
            closeSearchWhenClickingElsewhere(event, $scope.toggleSearch);
        };
    } else {
        $scope.open = false;
        $scope.$window.onclick = null;
        $scope.$apply(); //--> trigger digest cycle and make angular aware. 
    }
};

这是你的小提琴

我还尝试为搜索抽屉创建一个指令(如果有帮助的话(它需要一些修复:))。这是一个JSBin

2020-07-04