单击除特定元素

时间:2017-10-01 17:23:07

标签: angularjs

当我点击页面中的任意位置时ul元素(列出国家/地区)和suggestion-text输入元素(我输入国家/地区名称< / em>),控制器中的vm.suggested应设置为null。因此,ul元素将自动关闭。我怎么能这样做?

我已经看过Click everywhere but here eventAngularJS dropdown directive hide when clicking outside,其中讨论了自定义指令,但我无法解决如何使其适应我的示例。

enter image description here

标记

<div>
    <div id="suggestion-cover">
        <input id="suggestion-text" type="text" ng-model="vm.countryName" ng-change="vm.countryNameChanged()">
        <ul id="suggest" ng-if="vm.suggested">
            <li ng-repeat="country in vm.suggested" ng-click="vm.select(country)">{{ country }}</li>
        </ul>
    </div>

    <table class="table table-hover">
        <tr>
            <th>Teams</th>
        </tr>
        <tr ng-if="vm.teams">
            <td><div ng-repeat="team in vm.teams">{{ team }}</div></td>
        </tr>
    </table>

    <!-- There are many more elements here onwards -->
</div>

控制器

'use strict';

angular
    .module('myApp')
    .controller('readController', readController);

function readController() {
    var vm = this;

    vm.countryNameChanged = countryNameChanged;
    vm.select = select;

    vm.teams = {.....};
    vm.countryName = null;
    vm.suggested = null;

    function countryNameChanged() {
        // I have a logic here
    }

    function select(country) {
        // I have a logic here
    }
}

2 个答案:

答案 0 :(得分:0)

这只是一个例子,但您可以简单地点击主体,将列表重置为未定义。

这里的例子:

http://plnkr.co/edit/iSw4Fqqg4VoUCSJ00tX4?p=preview

你需要li元素:

$event.stopPropagation();

所以你的HTML:

<li ng-repeat="country in vm.suggested" ng-click="vm.select(country); $event.stopPropagation()">{{ country }}</li>

和你的身体标签:

<body ng-app="myWebApp" ng-controller="Controller01 as vm"  ng-click="vm.suggested=undefined;">

<强>更新

正如我所说,这只是一个例子,你可以把它放在身上,然后在那里捕捉点击,并播放&#39; closeEvent&#39;整个应用程序的事件。然后,您可以在控制器上监听该事件 - 然后关闭所有事件。这将是解决您的问题的一种方法,我发现它是相当不错的解决方案。

更新了plunker,显示了2个控制器之间的通信: http://plnkr.co/edit/iSw4Fqqg4VoUCSJ00tX4?p=preview

最后更新: 好的,最后一次尝试 - 创建一个指令或只是一个div并不重要,并在<li>元素打开时将其作为叠加层,并在点击时将其关闭。目前它是不可见的 - 您可以使用一些背景颜色来显示它。

更新了plunker: http://plnkr.co/edit/iSw4Fqqg4VoUCSJ00tX4?p=preview

最后完全不同的方法

经过一些考虑,我实际上看到我们从完全错误的角度看待问题,所以最终,在我看来这个问题的最佳解决方案是使用ng-blur并在功能上加上小超时如果有人选择了国家/地区,那么点击就足够了:

控制器上的

this.close = function () {
            $timeout(()=>{
              this.suggested = undefined;
            }, 200);
}

on html:

<input id="suggestion-text" type="text" ng-model="vm.countryName" ng-change="vm.countryNameChanged()" ng-blur="vm.close()">

通过这种方式,您不必在jQuery方式(您的解决方案)中执行此操作,而我在以前的所有解决方案中都试图避免这种方式。 这是plnker:http://plnkr.co/edit/w5ETNCYsTHySyMW46WvO?p=preview

答案 1 :(得分:0)

我通过在指令中调用控制器函数解决了这个问题,所以当用户点击元素的外部(页面中的任何位置)时,控制器函数会被指令触发。

查看

<ul ng-if="vm.suggested" close-suggestion="vm.closeSuggestion()">

<强>控制器

function closeSuggestion() {
    vm.suggested = null;
}

<强>指令

angular.module('myApp').directive('closeSuggestion', [
    '$document',
    function (
        $document
    ) {
        return {
            restrict: 'A',
            scope: {
                closeSuggestion: '&'
            },
            link: function (scope, element, attributes) {
                $document.on('click', function (e) {
                    if (element !== e.target && !element[0].contains(e.target)) {
                        scope.$apply(function () {
                            scope.closeSuggestion();
                        });
                    }
                });
            }
        }
    }
]);