2013-03-13 1 views
54

mi hanno una struttura HTML come questo: Due eventi click nidificate con angularjs

<div ng-click="test()"> 
    <div id="myId" ng-click="test2()"></div> 
    <div></div> 
    ... 
</div> 

Attualmente quando clicco sul div con l'id myId poi entrambe le funzioni ottenere innescato, ma voglio che appena test2 funzione get innescato. Come lo posso fare?

+0

Vedere anche http://stackoverflow.com/questions/14544741/angularjs-directive-to-stoppropagation in cui una direttiva è definito per fermare la propagazione. –

risposta

105

Tutto quello che dovete fare è fermare la propagazione dell'evento/gorgogliare.

Questo codice vi aiuterà a:

<div ng-click="test()">ZZZZZ 
    <div id="myId" ng-click="test2();$event.stopPropagation()">XXXXX</div> 
    <div>YYYYYY</div> 
    ... 
</div> 

Se i test e test2 funzioni apparirebbe come segue, si otterrebbe solo test2 nella tua console quando si fa clic su myId DIV. Senza $event.stopPropagation() si otterrebbe test2 seguito da test nella finestra di output della console.

$scope.test = function() { 
    console.info('test'); 
} 
$scope.test2 = function() { 
    console.info('test2'); 
} 
+1

ha funzionato come un incantesimo per me <3, grazie –

+0

Grande! È la soluzione più breve Grazie –

+3

Funziona anche con Angular2: '(click) =" test2(); $ event.stopPropagation() "' Grazie a – witters

30

Stessa risposta di Tom, ma po 'diverso.

 <div ng-click="test()"> 
      <div id="myId" ng-click="test2($event)">child</div> 
     </div> 

     $scope.test2 =function($event){ 
      $event.stopPropagation(); 
      console.log("from test2") 
     } 
     $scope.test =function(){ 
      console.log("from test") 
     } 
+0

+1 a questa risposta per mantenere la logica stopPropagation fuori dalla vista. – sma

+0

questa è la migliore risposta, grazie mille – Darktalker

+6

Penso che questa logica ** fa ** appartenga alla vista, perché altrimenti il ​​controller fa presupporre che la funzione interna sarà sempre chiamata da quel contesto, e che dovrà fermare la propagazione ogni volta. Questo rende il riutilizzo della funzione interiore molto limitato. Se la vista viene sempre rifatta, allora anche il controller. –

1

Ecco una direttiva in base a another question che supporta i collegamenti NG-href.

direttiva

'use strict'; 


var myApp = angular.module('myApp', [ 
    'ngAnimate' 
    ]); 

/** 
* @ngdoc directive 
* @name myMobileApp.directive:stopEvent 
* @description Allow normal ng-href links in a list where each list element itselve has an ng-click attached. 
*/ 
angular.module('myApp') 
    .directive('stopEvent', function($location, $rootScope) { 
    return { 
     restrict: 'A', 
     link: function(scope, element) { 
     element.bind('click', function(event) { 

     // other ng-click handlers shouldn't be triggered 
     event.stopPropagation(event); 
     if(element && element[0] && element[0].href && element[0].pathname) { 
      // don't normaly open links as it would create a reload. 
      event.preventDefault(event); 
      $rootScope.$apply(function() { 
      $location.path(element[0].pathname); 
      }); 
     } 
     }); 
     } 
    }; 
    }) 


.controller('TestCtrl', ['$rootScope', '$scope', 'Profile', '$location', '$http', '$log', 
    function($rootScope, $scope, Profile, $location, $http, $log) { 
    $scope.profiles = [{'a':1,'b':2},{'a':3,'b':3}]; 

    $scope.goToURL = function(path, $event) { 
     $event.stopPropagation($event); 
     $location.path(path); 
    }; 

    } 
]); 
<div ng-repeat="x in profiles" 
    ng-click="goToURL('/profiles/' + x.a, $event)"> 

     <a stop-event ng-href="/profiles/{{x.b}}">{{x}}</a> 

    </div>