0
我們有一個指令,顯示一個彈出, 在模板被加載彈出,與捕獲所有點擊文檔中的指令。角:事件取消綁定在指令並不會自動解除綁定完全
這種情況發生時它廣播一個事件來關閉彈出窗口,並解除綁定事件的$document
。
這是捕獲文件的指令點擊。
aOS.directive('catchOutsideClick',
[
'$document',
'eventsService',
function CatchOutsideClickDirective($document, eventsService) {
var CatchClick = function CatchClick(scope, element, attrs) {
// Check if there was clicked on parent or one of its children
function isDescendant(parent, child) {
var node = child.parentNode;
while (node !== null) {
if (node === parent) {
return true;
}
node = node.parentNode;
}
return false;
}
// Done clicking
var onOutsideClick = function onOutsideClick(event) {
var clickedItem = event.target;
if (!isDescendant(element[0], clickedItem) && element[0] !== clickedItem) {
eventsService.publish('clicked-outside-popup', element[0]);
$document.unbind('click', onOutsideClick);
}
};
// Catch clicks!
$document.bind('click', onOutsideClick);
};
return {
restrict: 'A',
scope: false,
link: CatchClick
};
}
]
);
這是加載彈出的HTML:
<div id="header" ng-controller="framework.header">
<div data-ng-include="popupTemplate"></div>
</div>
爲簡單起見,讓狀態控制器framework.header
將切換$scope.popupTemplate
對下面將呈現的HTML的路徑:
<div ng-controller="user.profle" catch-outside-click>
<!-- loads of content -->
</div>
的包括模板似乎完美地工作,但是這是我們現在看到的行爲:
- 您點擊按鈕來切換
popupTemplate
並將其加載到彈出的div中。 - 是很好的激發趕超外點擊指令,並綁定一個clickHandler事件對文檔
- 彈出裏面點擊什麼也不做(因爲這是在指令測試),但彈出外點擊很好地關閉因爲它廣播了在頭控制器中捕獲的事件。
- 單擊頁面中的任意位置不會再次觸發該指令,因此我們認爲它是正確解綁的。
- 除了點擊按鈕時再次打開彈出窗口。這似乎同時綁定了一個新的文檔點擊事件,但也立即觸發了clickhandler(這讓我覺得它觸發了第一個點擊處理程序)。
我不知道在這一刻如何測試是否觸發第一個或第二個點擊處理程序。
人有一個想法,我怎麼可以縮小下來,無論是我做的東西完全錯誤的,或者只是點我怎麼調試這個問題,看看哪些事件處理程序被觸發。
我覺得你不考慮事件冒泡考慮在內,如你綁定到點擊文檔INSIDE點擊處理器的後代元素?你只需要在按鈕點擊處理程序中調用event.stopPropagation() – schellmax