【发布时间】:2014-09-08 12:36:45
【问题描述】:
我一直在构建一个指令,允许用户从建议列表中进行选择(水平布局(类似于自动完成小部件)。
指令(称为“建议”)通过绑定到控制器模型来获取其数据源
我希望用户能够通过按“enter”键或单击鼠标按钮从建议列表中进行选择。
从建议框中选择一个项目后,整个框应该消失(即支持建议的模型应该变成一个空数组)
鼠标点击效果非常好 - 但是按回车键会导致 scope.items 中的新项目保留
您可以通过加载下面的示例来复制我所说的内容:
1 - 点击“添加”按钮 - 这将在指令范围的项目数组中添加一个项目“是的”并更新 DOM
2 - 用鼠标单击任何选项 - ng-click 效果极佳,建议消失
3 - 刷新页面并重复步骤 1 - 然后使用左右箭头键并按 Enter。除了“是”之外的一切都消失了
<body ng-controller="Ctrl">
<button ng-click="add()">add</button>
<h2>select:</h2>
<suggestions items="items" on-select="alert(selection)"></suggestions>
Javascript:
var app = angular.module('app', []);
app.controller('Ctrl', function ($scope) {
$scope.items = [
{name: 'foo', code: 1},
{name: 'bar', code: 2},
{name: 'tar', code: 3}
];
$scope.add = function () {
$scope.items.push({name: 'yea', code: 4});
};
$scope.alert = function (selection) {
console.log(selection);
$scope.items = [];
}
});
app.directive('suggestions', function () {
return {
scope: {
items: "=",
onSelect: "&onSelect"
},
link: function (scope, element) {
var currentIdx = -1;
scope.highlightItem = function (item) {
element.find('.suggestion-container>span.suggestion-item').removeClass('suggestion-item-selected');
$(item).addClass("suggestion-item-selected");
currentIdx = $(item).index();
};
// handle left, right arrow navigation
$(document).keydown(function (e) {
var spanSize = element.find('span.suggestion-item').size();
if (scope.items.length == 0 || currentIdx == -1)
return;
switch (e.which) {
case 37: // left
currentIdx = Math.max(currentIdx - 1, 0);
break;
case 39: // right
currentIdx = Math.min(currentIdx + 1, spanSize - 1);
break;
default:
return;
}
scope.highlightItem(element.find(".suggestion-container>span.suggestion-item:eq(" + currentIdx + ")"));
});
// handle enter key
$(document).keydown(function (e) {
if (scope.items.length <= 0 || currentIdx == -1)
return;
if (e.which == 13) {
scope.$apply(function () {
scope.onSelect({selection: scope.items[currentIdx]});
currentIdx = -1;
});
}
});
// handle hover
element.children('.suggestion-container').on('mouseenter', 'span.suggestion-item', function () {
scope.highlightItem(this);
});
element.children('.suggestion-container').on('mouseleave', function () {
element.find('.suggestion-container>span.suggestion-item').removeClass('suggestion-item-selected');
});
},
restrict: 'E',
template: '<div>{{items}}</div><div class="suggestion-container"><span ng-click="onSelect({selection:item})" class="suggestion-item" ng-repeat="item in items">{{item.name}}</span></div>'
};
});
风格
.suggestion-item-selected {
background-color: #46b8da;
cursor: pointer;
color: #ffffff;
}
.suggestion-item {
cursor: pointer;
padding-left: 2px;
padding-right: 2px;
border-width: thin;
border-style: solid;
border-color: #777777;
margin-right: 2px;}
谢谢,
【问题讨论】:
-
紧跟在“e.which == 13”块之后或内部的console.out 表明指令范围的项目确实已重置为空数组“[]”,即绑定有效。但随后对访问指令的 scope.items 的调用显示“是的”被重新添加进来。几乎看起来 Ctrl 的 add() 方法被无意中再次调用了。
标签: javascript angularjs