2013-03-13 11 views
54

Mam strukturę HTML tak: dwie zagnieżdżone zdarzenia kliknięcia angularjs

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

Obecnie po kliknięciu na div z identyfikatorem myId następnie obie funkcje się wyzwolony, ale chcę, że tylko test2 funkcja dostać rozsierdzony. Jak mogę to zrobić?

+0

Zobacz również http://stackoverflow.com/questions/14544741/angularjs-directive-to-stoppropagation gdy dyrektywa określa się powstrzymać rozprzestrzenianie. –

Odpowiedz

105

Wszystko, co musisz zrobić, to zatrzymać propagację/bulgotanie zdarzeń.

Kod ten pomoże Ci:

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

Jeśli test i test2 funkcje wyglądałby następująco, co można uzyskać tylko test2 w konsoli po kliknięciu na myId DIV. Bez $event.stopPropagation() otrzymasz test2, a następnie test w oknie wyjściowym konsoli.

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

pracował jak urok dla mnie <3, dzięki –

+0

Świetnie! To najkrótsze rozwiązanie. Dzięki –

+3

Działa również dla Angular2: '(kliknij) =" test2(); $ event.stopPropagation() "' Dzięki – witters

30

Tak samo jak odpowiedź Toma, ale niewiele różni.

 <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 dla tej odpowiedzi za utrzymanie logiki stopPropagation z widoku. – sma

+0

to jest najlepsza odpowiedź, bardzo dziękuję – Darktalker

+6

Myślę, że ta logika ** nie ** należy do widoku, ponieważ w przeciwnym razie kontroler przyjmuje założenie, że wewnętrzna funkcja będzie zawsze wywoływana z tego kontekstu i że będzie musiała zatrzymać propagację każdego razu. To sprawia, że ​​ponowne użycie funkcji wewnętrznej jest bardzo ograniczone. Jeśli widok zostanie kiedykolwiek refaktoryzowany, to także kontroler. –

1

Oto dyrektywa oparta na another question, która obsługuje łącza ng-href.

dyrektywa

'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> 
Powiązane problemy