我正在尝试创建下拉列表的自定义指令。
这是我的代码:https://plnkr.co/edit/YqJ6tz4fwvBRmtmzeCJr
要关闭下拉列表,请检查该指令元素之外的click事件。
$document.bind('click', function() {
scope.closeDropdown();
});
但是这段代码的问题是当一个下拉列表打开而另一个下拉列表点击时,第一个下拉列表不会关闭。
如果在点击另一个下拉列表时关闭下拉列表? 我可以通过在控制器中声明变量并在打开下拉列表之前每次检查来实现此目的。但通过这种方式,该指令不能单独使用。
任何帮助?
答案 0 :(得分:2)
一种方法是:
scope.toggleCheck = function(item,element){
scope.closeDropdown();
if(scope.multiSelect){
scope.multiChoice(item);
}else{
scope.singleChoice(item);
}
};
或更好的等待:
scope.openDropDown = function () {
$('.dropdown-list').css('display','none');
elem.find('.dropdown-list').css('display','block');
};
答案 1 :(得分:1)
您可以使用ng-class添加课程' show'这使得显示块
更新了模板
<div class="selector">
<div class="box-container">
<input type="text" class="search search-input" placeholder="{{dname}}" isDropDownInput="true" ng-model="userInput" />
<ul class="dropdown-list" ng-class="{show:showDropDown}">
<li ng-repeat="value in data | filter:userInput track by $index">
<span >
<input class="check-select" type="checkbox" value="{{value}}" ng-click="toggleCheck(value)" isdropdown="true" ng-checked="isChecked(value)"/>
{{value }}
</span>
</li>
</ul>
</div>
</div>
当用户点击窗口对象时,使用控制器切换类,这是更新的脚本,
(function(){
'use strict';
angular.module('app')
// safeApply service, courtesy Alex Vanston and Andrew Reutter
.factory('safeApply', [function ($rootScope) {
return function ($scope, fn) {
var phase = $scope.$root.$$phase;
if (phase == '$apply' || phase == '$digest') {
if (fn) {
$scope.$eval(fn);
}
} else {
if (fn) {
$scope.$apply(fn);
} else {
$scope.$apply();
}
}
}
}])
.directive('dropDown', dropDown);
function dropDown($document) {
var directive = {
restrict: 'EA',
replace: true,
scope: {
dname: '@',
data: '=',
selected : '=choices',
},
templateUrl: 'template.html',
link: linker,
controller: dropdownController
};
return directive;
function dropdownController($scope, $rootScope, $window, safeApply){
$window.onclick = function(event){
console.log("event target = " + event.target.attributes);
if(event.target.attributes && event.target.attributes.isDropDownInput){
$rootScope.$broadcast("closeAllDropDown", {'isDropDownInput':true, 'inputId':event.target.attributes.placeHolder.nodeValue})
}
else if(event.target.attributes && !event.target.attributes.isDropDown){
$rootScope.$broadcast("closeAllDropDown", {'isDropDownInput':false})
}
};
$scope.$on("closeAllDropDown", function(event,payload){
console.log("eventObj = " + event, payload.isDropDownInput);
if(payload.isDropDownInput){
if(event.currentScope.dname == payload.inputId){
event.currentScope.showDropDown = true;
}
else{
event.currentScope.showDropDown = false;
}
}
else{
$scope.showDropDown = false;
}
safeApply($scope);
console.log('$scope.showDropDown = ' + $scope.showDropDown)
});
$scope.openDropDown = function () {
$scope.showDropDown = true;
};
$scope.closeDropdown = function () {
$scope.showDropDown = false;
};
$scope.toggleCheck = function(item){
$scope.showDropDown = true;
if($scope.multiSelect){
$scope.multiChoice(item);
}else{
$scope.singleChoice(item);
}
};
$scope.isChecked = function (item) {
if ($scope.selected.indexOf(item) !== -1) {
return true;
}
return false;
};
$scope.singleChoice = function(item) {
$scope.selected.length = 0;
$scope.selected.push(item);
};
$scope.multiChoice = function (item) {
var index = $scope.selected.indexOf(item);
if(index > -1){
$scope.selected.splice(index, 1);
}else {
$scope.selected.push(item);
}
};
$scope.removeItem = function(item){
$scope.selected.splice($scope.selected.indexOf(item), 1);
};
}
function linker(scope, elem, attr) {
console.log('dropdown::loaded');
scope.showDropDown = false;
scope.selected = [];
scope.multiSelect = 'multiselect' in attr;
}
}
dropDown.$inject = ['$document'];
})();
希望它有助于而不是使用JQUERY