每次使用 $route.reload() 时如何防止我的自定义指令获得 compiled/executed
How can I prevent my custom directive from getting compiled/executed every time I use $route.reload()
我已经构建了一个自定义指令来启用下拉菜单中的箭头键导航。
这是我的HTML代码
<div ng-click="dropdownShow = !dropdownShow" id="dropdownToggle" arrow-navigation>
{{currentlySelectedItem}}
</div>
<div ng-show="dropdownShow">
<div ng-repeat="item in list" id="row_{{$index}}" ng-click="getItemInfo($index)">
<span>{{item}}</span>
</div>
</div>
还有我的JS代码
app.directive('arrowNavigation', ['$document', function($document){
return{
restrict: 'A',
link: function(scope, element, attrs){
$document.bind('keydown',function(e){
// check if dropdown open
if(scope.dropdownShow){
// if down arrow key pressed
if(e.keyCode === 40){
console.log("down arrow key pressed");
// When the dropdown is first opened, the focus will be on the dropdownToggle.
// In this case, I'm moving the focus to the first item on the list.
if(document.activeElement.id === "dropdownToggle"){
document.getElementById('row_0').focus();
}
else{
let currentFocused = document.activeElement.id;
// currentFocused = row_ + $index
let index = currentFocused.substring(4);
// index = $index of currently focused item
console.log(index);
index++;
// check if the currently focused item is the last item on the list
// In this case, move the focus back to the first item on the list
if(index >= scope.list.length){
document.getElementById('row_0').focus();
}
else{
document.getElementById('row_' + index).focus();
}
}
e.preventDefault();
}
// there's similar code for up arrow key press. I have decided to skip it for the sake of simplicity.
}
})
}
}
}])
我第一次使用下拉菜单时,一切正常。
但是当我 select 下拉列表中的任何项目时,生成的 ng-click 函数内部有一个 $route.reload
。这会导致我的 ng-view 重新加载。那就是问题开始的时候。第一次重新加载后,当我尝试使用下拉菜单时,每次单击箭头都会执行两次。因此,如果第一个列表项获得焦点,并且我按下向下箭头键,而不是将焦点移动到第二个项目,它会将焦点移动到第三个项目。随后每 $route.reload()
,执行次数增加一次。
我猜这是因为每次重新加载路由时都会重新呈现指令,导致同一指令的多个副本,然后所有这些副本都会在箭头单击时执行。
有什么办法可以防止重新渲染吗?
作用域被销毁时删除事件监听器
// inside link
scope.$on("$destroy", function() {
$document.unbind('keydown')
});
请注意,angular.element
绑定和解除绑定已弃用,因此我假设您可能使用的是相当旧的版本。最新版本使用 on()
和 off()
我已经构建了一个自定义指令来启用下拉菜单中的箭头键导航。
这是我的HTML代码
<div ng-click="dropdownShow = !dropdownShow" id="dropdownToggle" arrow-navigation>
{{currentlySelectedItem}}
</div>
<div ng-show="dropdownShow">
<div ng-repeat="item in list" id="row_{{$index}}" ng-click="getItemInfo($index)">
<span>{{item}}</span>
</div>
</div>
还有我的JS代码
app.directive('arrowNavigation', ['$document', function($document){
return{
restrict: 'A',
link: function(scope, element, attrs){
$document.bind('keydown',function(e){
// check if dropdown open
if(scope.dropdownShow){
// if down arrow key pressed
if(e.keyCode === 40){
console.log("down arrow key pressed");
// When the dropdown is first opened, the focus will be on the dropdownToggle.
// In this case, I'm moving the focus to the first item on the list.
if(document.activeElement.id === "dropdownToggle"){
document.getElementById('row_0').focus();
}
else{
let currentFocused = document.activeElement.id;
// currentFocused = row_ + $index
let index = currentFocused.substring(4);
// index = $index of currently focused item
console.log(index);
index++;
// check if the currently focused item is the last item on the list
// In this case, move the focus back to the first item on the list
if(index >= scope.list.length){
document.getElementById('row_0').focus();
}
else{
document.getElementById('row_' + index).focus();
}
}
e.preventDefault();
}
// there's similar code for up arrow key press. I have decided to skip it for the sake of simplicity.
}
})
}
}
}])
我第一次使用下拉菜单时,一切正常。
但是当我 select 下拉列表中的任何项目时,生成的 ng-click 函数内部有一个 $route.reload
。这会导致我的 ng-view 重新加载。那就是问题开始的时候。第一次重新加载后,当我尝试使用下拉菜单时,每次单击箭头都会执行两次。因此,如果第一个列表项获得焦点,并且我按下向下箭头键,而不是将焦点移动到第二个项目,它会将焦点移动到第三个项目。随后每 $route.reload()
,执行次数增加一次。
我猜这是因为每次重新加载路由时都会重新呈现指令,导致同一指令的多个副本,然后所有这些副本都会在箭头单击时执行。
有什么办法可以防止重新渲染吗?
作用域被销毁时删除事件监听器
// inside link
scope.$on("$destroy", function() {
$document.unbind('keydown')
});
请注意,angular.element
绑定和解除绑定已弃用,因此我假设您可能使用的是相当旧的版本。最新版本使用 on()
和 off()