2013-07-23 10 views
7

Tutaj jest dyrektywa, w której ja próbuje wyłączyć łącza na podstawie wartości Model:zdarzenie Wyłączenie ngClick obsługi w dyrektywie niestandardowego

app.directive('disableable', function($parse){ 
    return { 
     restrict: 'C', 
     require: '?ngClick', 
     link: function (scope, elem, attrs, ngClick) { 
      if (attrs.disable){ 
       var disable = $parse(attrs.disable); 

       elem.bind('click', function (e) { 
        if (disable(scope)){ 
         e.preventDefault(); 
         return false; 
        } 

        return true; 
       }); 

       scope.$watch(disable, function (val) { 
        if (val){ 
         elem.addClass('disabled'); 
         elem.css('cursor', 'default'); 
        } 
        else { 
         elem.removeClass('disabled'); 
         elem.css('cursor', 'pointer'); 
        } 
       }); 
      } 
     } 
    }; 
}); 

Chcę być w stanie wyłączyć wszystkie działania łącza, niezależnie czy używają prostych hrefów czy działań ngClick. Hrefs działa dobrze z powodu wywołania preventDefault, ale nie mogę wymyślić, jak zagłębić się w NgClick i zapobiec jego uruchomieniu. Wiązanie, które robię w przypadku zdarzenia kliknięcia, nie działa, ponieważ wydaje się, że ngClick wiąże swój własny program obsługi, nad którym nie mam kontroli. Czy jest coś, co mogę zrobić?

jsFiddle: http://jsfiddle.net/KQQD2/2/

Odpowiedz

8

Korzystając event.stopImmediatePropagation.

Od MDN:

Jeżeli kilka słuchacze są przyłączone do tego samego elementu dla tego samego typu zdarzeń, nazywane są w kolejności, w jakiej zostały dodane. Jeśli podczas jednego takiego wywołania, wywoływana jest funkcja event.stopImmediatePropagation(), nie będą wywoływane pozostałe detektory .

... 
elem.bind('click', function (e) { 
    if (disable(scope)){ 
    e.stopImmediatePropagation(); 
    return false; 
    } 

    return true; 
}); 
... 

WORKING FIDDLE

+1

stopImmediatePropagation działa dobrze aż do v1.0.8, od v1.2.0 nie. testowane na pokrewnym skrzypcach. –

4

można zrobić po prostu zmienić ng kliknięciem disableIt || tellAboutIt() i będzie działać jak jest. np

<a class="disableable" target="_blank" ng-click="disableIt || tellAboutIt()"> 
      ngClick disableable link</a> 

Pełny kod:

HTML (I zostały usunięte 'wyłączone' atrybutów, ponieważ są one bezużyteczne, ponieważ nie działają na znaczniki kotwiących):

<div ng-app="app" ng-controller="appCtrl"> 
    <a class="disableable" target="_blank" ng-click="disableIt || tellAboutIt()"> 
     ngClick disableable link</a> 
    <br/><br/> 
    <a class="disableable" target="_blank" href="http://google.com"> 
     href disableable link</a> 
    <br/><br/> 
    <input type="checkbox" ng-model="disableIt" /> Disable links 
</div> 

Angular (Zmieniliśmy twoją dyrektywę):

app.directive('disableable', function($parse){ 
    return { 
     restrict: 'C', 
     link: function (scope, elem, attrs) { 
      scope.$watch('disableIt', function (val) { 
       if (val) { 
        elem.addClass('disabled'); 
        elem.css('cursor', 'default'); 
        elem.bind('click', function(e) { 
         e.preventDefault(); 
        }); 
       } 
       else { 
        elem.removeClass('disabled'); 
        elem.css('cursor', 'pointer'); 
        if (typeof elem.attr('ng-click') === 'undefined') 
         elem.unbind('click'); 
       } 
      }); 
     } 
    }; 
}); 

JSFiddle: http://jsfiddle.net/KQQD2/4/


Alternatywnie, można sprawdzić $scope.disableIt jest fałszywa przed uruchomieniem kodu wewnątrz tellAboutIt(). np .:

$scope.tellAboutIt = function(){ 
    if ($scope.disableIt === false) { 
     $window.alert('ngClick fired. This alert should not show when disabled.'); 
    } 
}; 
0

Prawdopodobnie przydałby się nieco inny sposób. Zamiast próbować się wcisnąć ng-click za pomocą innej dyrektywy. Po prostu napisałem własną wersję ng-click i użyłem jej zamiast tego, aby można było włączać/wyłączać przy użyciu osobnego atrybutu. Jeśli to zrobisz, kod, który napisałeś powyżej, nie będzie musiał wiele zmieniać, aby to zrobić, i możesz po prostu użyć tej dyrektywy zamiast ng-click.

app.directive('enabled-click', function() { 
    return { 
     scope: { 
      enabledClick: '&', 
      enabled: '=' 
     }, 
     restrict: 'A', 
     link: function(scope, element, attributes) { 
      element.bind('click', function(event) { 
       if(scope.enabled) { 
        if(element.target) { 
        return true; // external link 
        } else { 
        scope.enabledClick(); 
        return false; 
        } 
       } else { 
        event.preventDefault(); 
        return false; 
       } 
      }); 
      scope.$watch('enabled', function(val) { 
       if(val) { 
        element.removeClass('disabled'); 
       } else { 
        element.addClass('disabled'); 
       } 
      }); 
     } 
    }; 
}); 

Potem go używać:

<a href="#something" enabled-click="doSomething()" enabled="!disable">Blah</a> 
Powiązane problemy