Javascript angularjs-绑定到父控制器变量后未清理指令范围
我一直在构建一个指令,允许用户从水平排列的建议列表中进行选择,类似于自动完成小部件 名为“建议”的指令通过绑定到控制器模型来获取其数据源 我希望用户能够通过按enter键或单击鼠标按钮从建议列表中进行选择 从建议框中选择一项后,整个框将消失,即支持建议的模型将变为空数组 鼠标点击效果非常好-但是按enter键会使scope.items中的新项目保留下来 通过加载下面的示例,您可以复制我所说的内容: 1-单击add按钮-这将向指令范围的items数组中添加item yea并更新DOM 2-用鼠标点击任何选项-点击效果极佳,建议消失 3-刷新页面并重复步骤1-然后使用左右箭头键并按enter键。除了“是”之外,一切都消失了Javascript angularjs-绑定到父控制器变量后未清理指令范围,javascript,angularjs,Javascript,Angularjs,我一直在构建一个指令,允许用户从水平排列的建议列表中进行选择,类似于自动完成小部件 名为“建议”的指令通过绑定到控制器模型来获取其数据源 我希望用户能够通过按enter键或单击鼠标按钮从建议列表中进行选择 从建议框中选择一项后,整个框将消失,即支持建议的模型将变为空数组 鼠标点击效果非常好-但是按enter键会使scope.items中的新项目保留下来 通过加载下面的示例,您可以复制我所说的内容: 1-单击add按钮-这将向指令范围的items数组中添加item yea并更新DOM 2-用鼠标点
<body ng-controller="Ctrl">
<button ng-click="add()">add</button>
<h2>select:</h2>
<suggestions items="items" on-select="alert(selection)"></suggestions>
谢谢,回答了我自己的问题:
原因是再次调用add。按左-右键也会产生副作用,即将添加按钮聚焦在e之后或e内部的console.out上,e==13块显示指令作用域的项确实已重置为空数组“[]”,即绑定工作。但随后访问该指令的scope.items的调用显示“yea”已添加回。似乎Ctrl的add方法被无意中再次调用了。
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;}