我有一个自定义指令,其内部有一个弹出菜单,当我点击指令中的一个按钮时应显示该指令,只要我在指令外单击它就应该关闭。
我将指令用于列表中的多个项目,因此页面上总会有多个此指令。
现在我有一些代码正在侦听文档上的点击。我已将此代码移动到我的控制器,因为它根据页面上的指令数量进行了x次评估。
我能做些什么来保持指令中的所有代码?
// BOTTOM OF MY CONTROLLER //
// function to be called when clicking outside the directive/menu
onDocumentClick = function(event){
// if not clicked on an .popup-btn then remove all classnames from popup-menu
activeNodes = document.getElementsByClassName("popup-menu active");
if(activeNodes.length >= 1){
clicked_el = angular.element(event.target);
if(!/^popup-btn|popup-menu/.test(clicked_el[0].className)){
for (var i = 0; i < activeNodes.length; i++){
activeNodes[i].className = "popup-menu";
console.log(activeNodes[i]);
}
}
}
};
$document.on('click', onDocumentClick);
}]);
// END OF CONTROLLER //
//Directive
mealplan.directive('recipe', ['$document', function($document) {
return {
restrict: 'AE',
scope: {
item: '=recipe'
},
link: function(scope, elem, attrs) {
// toggle the recipe menu
scope.toggleMenu = function() {
console.log("toggle menu");
// loop throug all menus and reset their class names
activeNodes = document.getElementsByClassName("popup-menu active");
if(activeNodes.length >= 1){
for (var i = 0; i < activeNodes.length; i++){
activeNodes[i].className = "popup-menu";
console.log(activeNodes[i]);
}
}
// set the current
current = elem[0].getElementsByClassName("popup-menu")[0];
current.className = "popup-menu active";
console.log(current);
};
// initializes the states
scope.init = function() {
//scope.currentMenu = null;
};
scope.init();
},
templateUrl: 's/recipes/js/popupMenu-directive.html'
};
}]);
答案 0 :(得分:1)
在返回options对象之前在指令中执行的代码只执行一次。
myApp.directive('uiJq', function InjectingFunction(){
// === InjectingFunction === //
// Logic is executed 0 or 1 times per app (depending on if directive is used).
// Useful for bootstrap and global configuration
// Do the binding here
return {
compile: function CompilingFunction($templateElement, $templateAttributes) {
// Logic is executed once (1) for every instance of ui-jq
return function LinkingFunction($scope, $linkElement, $linkAttributes) {
// Logic is executed once (1) for every RENDERED instance.
};
}
};
})
您可以在声明指令后绑定事件处理程序,并且只执行一次。
答案 1 :(得分:0)
不是很优雅,但您可以使用.off
删除绑定(如果已存在),然后设置.on
事件。
$document.off('click.some-namespace');
$document.on('click.some-namespace', function() { ... });
使用事件命名空间保持其他任何点击事件不变。这样,无论指令的使用次数如何,事件都应该绑定一次。