2014-05-05 43 views
0

內的所有NG-點擊我有一個指令disable-ng-clicks並在一定條件下,我想阻止所有NG-點擊是該指令的孩子。下面是一些例子標記:動態禁用元素

<div disable-ng-clicks> <!-- directive --> 
    <a ng-click="someAction()"></a> 
    <div ng-controller="myController"> 
    <a ng-click="anotherAction()"></a> 
    <a ng-click="moreActions()"></a> 
    </div> 
</div> 

如果這些都是正常的超鏈接,我可以做這樣的事情在link功能:

function(scope, iElement, iAttrs) { 
    var ngClicks = angular.element(iElement[0].querySelectorAll('[ng-click]')); 
    ngClicks.on('click', function(event) { 
    if(trigger) { // a dynamic variable that triggers disabling the clicks 
     event.preventDefault(); 
    } 
    }); 
} 

但是,這並不爲ng-click指令工作。有沒有另外一種方法來完成這個?

+1

那麼您點擊元素不是DIV,是錨。你應該把它放在每個錨點中,或者改變指令來禁止子元素的ng-click。你在做的方式它只適用於有指令的元素。 – Fals

+0

我不確定我的理解。我可以將點擊處理程序附加到父項上,並在點擊某個子項時執行它。 – thetallweeks

+0

是的,你可以這樣做,但你需要更改指令來尋找從有它的每一個元素chield。 – Fals

回答

1

這是我能想到的最好的。我創建了一個新的指令來代替NG點擊:

directive('myClick', ['$parse', function($parse) { 
    return { 
    restrict: 'A', 
    compile: function($element, attrs) { 
     var fn = $parse(attrs.myClick); 
     return function (scope, element, attrs) { 
     var disabled = false; 
     scope.$on('disableClickEvents', function() { 
      disabled = true; 
     }); 
     scope.$on('enableClickEvents', function() { 
      disabled = false; 
     }); 
     element.on('click', function (event) { 
      if (!disabled) { 
      scope.$apply(function() { 
       fn(scope, { $event: event }); 
      }); 
      } 
     }); 
     }; 
    } 
    } 
}]); 

所以在不同的指令,我可以有:

if (condition) { 
    scope.$broadcast('disableClickEvents'); 
} 

,當我想重新啓用:

if (otherCondition) { 
    scope.$broadcast('enableClickEvents'); 
} 

我不喜歡使用的NG-點擊不同的指令,但是這是我能想到的最好的計劃。

+0

我只是將它標記爲答案,因爲它可以滿足我的需求。 – thetallweeks

0

因爲JS events bubbling,你正在捕獲父節點上的'click'事件,所以如果你想攔截所有的後代,所以你的指令應該得到當前元素的所有後代,監聽它們的'click'事件,並防止它if必要。

+0

你可以發佈示例代碼?我可以用ng-click來獲取所有後代,但即使我嘗試運行event.preventDefault(),它也發生得太晚,因爲Angular的ng-click已經作爲點擊處理程序接管了。 – thetallweeks

+0

ng-click事件不是默認操作,這是event.preventDefault()阻止的操作。相反,您需要取消註冊點擊事件 - 查看我的答案以獲取示例指令。 –

+0

我更新了問題,這是我的錯誤。 – thetallweeks

0

這個指令會遍歷所有子元素,檢查,看看他們是否有NG,點擊屬性,如果他們這樣做,這將禁用所有已註冊的單擊事件處理程序:

directive('disableNgClicks', function(){ 
    return { 
    restrict: 'E', 
    link: function(scope, elem, attrs){ 
     angular.forEach(elem.children(), function(childElem) { 
     if (childElem.outerHTML.indexOf("ng-click") > -1) { 
      angular.element(childElem).off('click'); 
     } 
     }); 
    } 
    } 
}) 

Plunker demo

+0

而不是取消註冊點擊事件,我寧願'stopImmediatePropagation',因爲我想打開和關閉這個。不幸的是,我無法讓我的指令在ng-click之前執行它的點擊處理程序。我發現[優先](http://stackoverflow.com/questions/16208899/intercepting-ng-click-in-angularjs)規定了當兩個指令位於同一個元素上時的順序,但是當其中一個是父代時,不知道如何控制哪個點擊處理程序首先觸發。 – thetallweeks

+0

是的,很容易防止每個元素的ng-click事件,但我沒有看到任何顯而易見的方式來使用父指令覆蓋​​他們的行爲,同時允許禁用。正如你所發現的,排序是一個真正的問題。我認爲你最好的選擇是使用一個範圍變量來防止在設置爲true時調用ng-click處理程序:http://stackoverflow.com/questions/14545744/how-to-make-a-condition -on-ng-click-in-angularjs –

+0

小評論。該指令必須限制:'A'使用@thetallweeks代碼。 –

0

我知道這是2年前,但我需要做同樣的事情,用一個相當簡單的解決方案上來。

對象:

items: { 
    item1 : { 
     selected: 0, 
     other: 'stuff' 
    }, 
    item2 : { 
     selected : 1, 
     other: 'stuff' 
    } 
} 

的HTML:

<div ng-repeat="item in items" ng-model="item.selected" ng-click="selectParent($event)"> 
    <div ng-click="item.selected ? selectChild($event) : null">Child</div> 
</div> 

功能:

$scope.selectParent = function($event) { 
    var itemScope = angular.element($event.currentTarget)scope().item; 
    itemScope.selected = !itemScope.selected; 
} 

$scope.selectChild = function($event) { 
    $event.stopPropagation; 
    console.log('I only get triggered if parent item is selected'); 
} 

這是什麼,我做了一個非常原始的例子。你或許應該使用一個指令,讓您$範圍,而不是angular.element($ event.currentTarget).scope ......無論哪種方式,如果邏輯是什麼,我真的越來越在簡單的內聯。您可以根據某個值調用函數或不調用函數。