2013-08-20 11 views
7

Mam następujący kod. Pętla nad JSON, aby utworzyć zagnieżdżoną listę ul. Mam zdarzenie click, które wykonuje funkcję toggleNav() powiązaną z tagiem zakotwiczenia. Nie wiem, dlaczego zdarzenie kliknięcia związane jest dwukrotnie z elementem. Poza tym jestem nowy w kanciastym, czy istnieje dokument wyjaśniający tę koncepcję? Dzięki!Angular JS: Dlaczego moje zdarzenie kliknięcia jest uruchamiane dwa razy?

define([ 
'/assets/angularapp/AppDirectives.js', 
'highstock' 
], function (directives) { 
directives.directive('collection', function() { 
    return { 
     restrict: "E", //declare by element 
     replace: true, 
     scope: { 
      collection: '=' 
     }, 
     template: "<ul class=\"nav nav-list tree\"><member ng-repeat=\"member in collection\" member=\"member\"></member></ul>" 
    } 
}) 

directives.directive('member', function ($compile) { 

    return { 
     restrict: "E", 
     replace: true, 
     scope: { 
      member: '=' 
     }, 
     template: "<li ng-show=\"member.open\"><span><input type=\"checkbox\" ng-model=\"member.selected\" class=\"sideChkbox\"><a class=\"tree-toggle\" ng-click=\"toggleNav()\"><i class=\"icon-chevron-right\"></i>{{member.data}}</a></span></li>", 
     controller: function($scope, $element){ 
      $scope.toggleNav = function(){ 
       angular.forEach($scope.member.children,function(child,key){ 
        if(child.open==true){ 
         alert("a") 
         child.open=false; 
        } else { 
         child.open=true; 
         alert("b") 

        } 

       }) 

      } 
     }, 
     link: function (scope, element, attrs) { 
      if (angular.isArray(scope.member.children)) { 
       element.append("<collection collection='member.children'></collection>"); 
       $compile(element.contents())(scope) 
      } 
     } 
    } 
}) 
+0

Czy można zrzucić razem skrzypce pokazujące to, nie widzę niczego oczywistego, które powinno wywoływać dwa wywołania do obsługi. Ale możliwość sprawdzenia DOM po zastosowaniu dyrektyw może doprowadzić do pewnego wglądu. Jesteś pewny, że nie dostajesz wielokrotnych iteracji pętli w programie obsługi, to jest to, że dzwoni się do obsługi wielokrotnie? – shaunhusain

+0

Czy mówisz o pętli foreach wyzwala dwa alerty? Być może kolekcja zawiera dwa elementy, ale funkcja jest nadal związana tylko raz. – zsong

+1

Zrobiłem skrzypce, aby sprawdzić problem, widzę dokładnie to, co mówisz i szczerze nie masz pojęcia, dlaczego to się dzieje: http://jsfiddle.net/rEz52/1/ – shaunhusain

Odpowiedz

13

To dlatego, że jesteś kompilacji element.contents(), w tym < > z ng-click, który powinien być już skompilowany. W momencie, w którym wywołujesz ręczną kompilację, zostaje ona ponownie skompilowana.

można naprawić przez to:

... 
    if (angular.isArray(scope.member.children)) { 
     var newMemEL = angular.element("<collection collection='member.children'></collection>"); 
     element.append(newMemEL); 
     $compile(newMemEL)(scope); 
    } 
    ... 

Wygląda na to, że starają się tworzyć katalogów, w tym przypadku, to byłoby lepiej użyć ngInclude zamiast tworzenia dyrektyw niestandardowych, przyjrzeć się to plunker, zauważ, że nie będzie działać z Angular 1.2.0rc1 z powodu tej

2

@ Odpowiedź Mr.DucNguyen jest poprawna, ale jeśli nie chcesz dalej manipulować DOM, możesz podejść do niego w inny sposób.

Oznacz element jako ukończony podczas funkcji łączenia, więc gdy spróbuje połączyć ponownie, nie powiedzie się.

link: function (scope, element, attrs) { 
    // stop an already linked element from continuing 
    if (element.attr('collection-linked')) { 
     return; 
    } 
    // otherwise, add a completed flag to this element 
    element.attr('collection-linked', true); 

    // continue your linking ... 
} 
Powiązane problemy