2013-08-20 8 views
7

私は以下のコードを持っています。 JSONをループしてネストされたulリストを生成します。アンカータグにバインドされた関数toggleNav()を実行するclickイベントがあります。なぜクリックイベントが要素に2回バインドされているのかわかりません。また、私は角に新しいです、そこにこのコンセプトを説明する文書がありますか?ありがとう!Angular JS:クリックイベントが2回発生するのはなぜですか?

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

これを示すフィーリングを一緒に投げることができますか、私はハンドラへの2回の呼び出しを引き起こすはずの何も明らかではありません。しかし、ディレクティブを使用した後にDOMを検査できるようになると、いくつかの洞察が得られる可能性があります。実際にハンドラを複数回呼び出すことは、ハンドラ内でループの複数の繰り返しを取得するだけではないことも確かですか? – shaunhusain

+0

foreachループが2つのアラートをトリガするとお考えですか?おそらくコレクションに2つの要素が含まれていても、その関数はまだ1回バインドされています。 – zsong

+1

私は問題を調べるために魔法を作った、私はちょうどあなたが何を言っているのかを正直に見て、なぜそれが起こっているのか分かりません:http://jsfiddle.net/rEz52/1/ – shaunhusain

答えて

13

あなたはすでにコンパイルされなければならないNGクリック、と< >含むelement.contentsを()、コンパイルされているからです。手作業でコンパイルを呼び出すと、再びコンパイルされます。

あなたは、このことによってそれを修正することができます。

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

あなたがツリービューを作成しようとしているように見え、この場合には、見ている、カスタムディレクティブを作成するのではなく、ngIncludeを使用する方が良いだろうこのplunkerは、これにより角度1.2.0rc1で動作しないことに注意してください。issue

2

@ Mr.DucNguyenの回答は正しいですが、DOMをさらに操作したくない場合は、別の方法でアプローチできます。

リンク機能中に要素を完了したものとしてフラグを立てます。したがって、リンクを再度試みると失敗します。

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 ... 
} 
関連する問題