2013-08-24 15 views

Odpowiedz

28

Nie można zastąpić wbudowanych dyrektyw AngularJS. Można jednak zdefiniować wiele dyrektyw o tej samej nazwie i wykonać je dla tego samego elementu. Przypisując odpowiednią dyrektywę priority, możesz wtedy kontrolować, czy twoja dyrektywa działa przed czy po wbudowanej dyrektywie.

Ten plunker pokazuje, jak zbudować dyrektywę ng-click, która jest wykonywana przed wbudowanym ng-click. Kod jest również pokazany poniżej. Po kliknięciu linku najpierw zostanie uruchomiony niestandardowy ng-click, a następnie wbudowany ng-click.

index.html

<!DOCTYPE html> 
<html ng-app="app"> 

    <head> 
    <script data-require="[email protected]" data-semver="1.9.0" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.js"></script> 
    <script data-require="[email protected]" data-semver="1.0.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js"></script> 
    <script src="script.js"></script> 
    </head> 

    <body ng-controller="MyCtrl"> 
    <a ng-click="alert()">Click me</a> 
    </body> 

</html> 

script.js

angular.module('app', []) 
    .directive('ngClick', function($rootScope) { 
     return { 
     restrict: 'A', 
     priority: 100, // give it higher priority than built-in ng-click 
     link: function(scope, element, attr) { 
      element.bind('click', function() { 
      // do something with $rootScope here, as your question asks for that 
      alert('overridden'); 
      }) 
     } 
     } 
    }) 
    .controller('MyCtrl', function($scope) { 
    $scope.alert = function() { 
     alert('built-in!') 
    } 
    }) 
+1

Bardzo dziękuję za szczegółową odpowiedź) – Simcha

+0

Buu, czy możemy całkowicie zatrzymać pierwsze kliknięcie? mam na myśli po uruchomieniu "przesłoniętego" alertu, "wbudowany", aby nie działać. –

+0

Nie należy przekazywać wyrażenia do ng-click, zobacz http://plnkr.co/edit/uROkIcGKLspLnVsjmAKn?p=prewview. Jeśli musisz przekazać s/t, nie obsługuj tego, np. $ scope.alert = function() {}. –

71

Każda dyrektywa jest specjalną usługą wewnątrz angularjs można zastąpić lub zmodyfikować dowolną usługę w angularjs, w tym dyrektywy

Na przykład usuń wbudowany ngClick

angular.module('yourmodule',[]).config(function($provide){ 
    $provide.decorator('ngClickDirective', ['$delegate', function($delegate) { 
     //$delegate is array of all ng-click directive 
     //in this case first one is angular buildin ng-click 
     //so we remove it. 
     $delegate.shift(); 
     return $delegate; 
    }]); 
}); 

kątowe wsparcia wielu dyrektyw o tej samej nazwie, dzięki czemu można zarejestrować jesteś właścicielem ngClick dyrektywa

angular.module('yourmodule',[]).directive('ngClick',function(){ 
    return { 
    restrict : 'A', 
    replace : false, 
    link : function(scope,el,attrs){ 
     el.bind('click',function(e){ 
     alert('do you feeling lucky'); 
     }); 
    } 
    } 
}); 

Wyjazd http://plnkr.co/edit/U2nlcA?p=preview pisałem próbkę że usunięte kątowe wbudowaną ng-click i dodać niestandardowe ngClick

+0

To było dla mnie niezwykle pomocne! Dzięki. –

+1

W jaki sposób zachowałbyś oboje delegatów, ale pozwoliłbyś, aby pierwszy przewodnik rozpowszechniał się warunkowo do wbudowanego uczestnika? –

+0

@AlexWhite przypuszczam, że jest to niemożliwe, ponieważ wiązanie 'click' jest wykonywane z' element.bind' wewnątrz innego wywołania funkcji: https://github.com/angular/angular.js/blob/master/src/ ng/directive/ngEventDirs.js # L62 – saiyancoder

Powiązane problemy