2013-07-12 31 views
2

我在Angular中遇到了一種情況,我感覺我做錯了什麼,但是我找不到解決它的Angular方法。如何編寫指向鉤入ng-click處理程序的指令

我正在開發一個移動應用程序。我想創建一個指令,我們將其稱爲cc-tap-highlight,它將與ng-click一起使用。這意味着我可以用這樣的:

<a ng-click="doSomething()" cc-tap-highlight>Click me</a> 

這是什麼會做的是一類添加到點擊的元素,並在幾秒鐘後刪除它。

現在可以說,讓我們手動綁定到指令中的元素click事件。這將適用於桌面應用程序。然而,在移動設備上Angular做了很多神奇的,我們有快速的點擊/點擊:

https://github.com/angular/angular.js/blob/master/src/ngMobile/directive/ngClick.js

可以肯定,我不想重新實現這一切的魔力!

因此,目前的而不是我的cc-tap-highlight指導我用這個相當hackish的方法:

在視圖

<a ng-click="doSomething($event)" cc-tap-highlight>Click me</a> 

在控制器:

$scope.doSomething = function($event){ 
    //do your things with $event.currentTarget 
} 

主要有兩種這種方法的問題:

  1. 控制器將不操作DOM

  2. 我們需要通過我們的整個代碼庫一遍又一遍地重複拍打違反幹

但是,我不能爲我的生活,弄清楚如何編寫一個指向掛鉤到ng-click處理程序的指令並做它的事情。

回答

2

您可以嘗試使您的指令生成帶包裝函數的ng-click指令。

Here's一個簡單的例子。目前還沒有經過徹底的測試,但我認爲原理是正確的。你想要的是你的自定義代碼在點擊事件之前/之後運行,不管觸發如何(點擊,點擊,等等)。

這樣做的缺點是它會創建一個新的作用域,因此與可能需要隔離作用域的其他指令的交互沒有經過測試。

DIRECTIVE

app.directive('myClick', ['$parse','$compile', function($parse, $compile) { 
    return { 
    restrict: 'A', 
    compile : function(tElement, tAttrs, transclude) { 
     //you can call the wrapper function whatever you want. 
     //_myClick might be more appropriate to indicate it's not really public 
     tElement.attr('ng-click', 'myClick($event)'); 
     tElement.removeAttr('my-click'); 
     var fn = $parse(tAttrs['myClick']); 

     return { 
     pre : function(scope, iElement, iAttrs, controller) { 
      console.log(scope, controller); 
      scope.myClick = function(event) { 
      console.log('myClick.before'); 
      fn(scope, {$event:event}); 
      console.log('myClick.after'); 
      }; 

      $compile(iElement)(scope); 
     }, 
     post : function postLink(scope, iElement, iAttrs, controller) { 

     } 
     }; 
    }, 
    scope : true 
    }; 
}]); 

控制器

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'World'; 

    $scope.test = function($event) { 
    console.log('test', $event); 
    }; 

    //this is to show that even if you have a function with the same name, 
    //the wrapper function is still the one bound thanks to the new scope 
    $scope.myClick = function() { 
    console.log('dummy my click'); 
    }; 
}); 

HTML

<button ng-click="test($event)">NG-CLICK</button> 
<button my-click="test($event)">MY-CLICK</button> 
<button ng-click="myClick($event)">MY-CLICK-DUPLICATE-FN</button> 
+2

,將工作,但它也是一個格雷亞因爲它意味着在任何需要的地方用'my-click'取代'ng-click'。我認爲真正的修復需要在Angular框架內部進行。他們應該直接在元素上觸發一個事件,以便在編寫指令時綁定該事件。我創建了一個問題和一個PR,但它需要更多的工作。 https://github.com/angular/angular.js/issues/3218 – Christoph