2013-03-13 71 views
4

我有這一塊的HTMLAngular.js,取消NG單擊事件

<button ui:confirm ng:click="action"></button> 

的和JavaScript代碼

.directive('uiConfirm', function() 
{ 
    return { 
     restrict: 'A', 
     link: function(scope, element, attrs) 
     { 
      element.bind('click.confirm', function(event) 
      { 
       event.preventDefault(); 
       event.stopPropagation(); 
      }); 
     } 
    } 
}) 

現在,我想要做的,就是取消ng:click事件,從指令中。 但ng:無論我做什麼,點擊仍然會被觸發。

演示:Fiddle

編輯: 順便提及,在此範圍內產生誤差:

element.bind('click.confirm', function(event) 
{ 
    causeAnError(); 
    event.preventDefault(); 
    event.stopPropagation(); 
}); 

是否招,和canceles事件傳播,而且還引發和難看的錯誤= )

編輯2: 最後我找到了解決方案!

.directive('uiConfirm', function() 
{ 
    return { 
     restrict: 'A', 
     link: function(scope, element, attrs) 
     { 
      element.bind('click', function(event) 
      { 
       scope.$eval(attrs.uiConfirm); // this line of code does the magic! 
      }); 
     } 
    } 
}) 

編輯3:

最終解決

.directive('uiConfirm', function() 
{ 
    return { 
     restrict: 'A', 
     link: function(scope, element, attrs) 
     { 
      /** 
      * Clicking the trigger start the confirmation process. 
      */ 
      element.bind('click.confirm', function(event) 
      { 
       // not confirmed? 
       if(! element.data().confirmed) 
       { 
        element.data().confirmed = true; 
        element.addClass('btn-danger'); 
       } 
       // is already confirmed.. 
       else 
       { 
        element.trigger('mouseout.confirm'); 
        scope.$eval(attrs.uiConfirm); 
       } 
      }); 

      /** 
      * Leaving the element, resets the whole process. 
      */ 
      element.bind('mouseout.confirm', function() 
      { 
       // reset all values 
       element.data().confirmed = false; 
       element.removeClass('btn-danger'); 
      }); 

      // reset the whole process on the first run 
      element.trigger('mouseout.confirm'); 
     } 
    } 
}) 

點擊一個按鈕,在第一時間,要讓它紅色,並且不會觸發任何動作。單擊第二次,調用該操作。離開按鈕重置整個過程。

+1

@Arun P約翰尼 - 謝謝你小提琴! – 2013-03-13 13:19:47

+0

您正在嘗試執行的操作可能與此https://groups.google.com/forum/#!msg/angular/ADylKzNT5oI/n6ZagosZZgsJ – 2013-03-13 13:24:30

+0

@ArunPJohny相關我已經看到了這一點,但這是另一種場景。 – 2013-03-13 13:27:37

回答

2

正如評論上@討論Flek的回答,來調用屬性定義的函數,

ui:confirm="action()" 

使用scope.$eval()

element.bind('click', function(event) { 
    scope.$eval(attrs.uiConfirm); // calls action() on the scope 
}); 
+1

從角度1.2.0-rc.3和可能更早的角度來看,您應該使用'scope。$ apply()',以便任何影響範圍的操作都會顯示出來... – JustMaier 2013-11-08 21:40:23

+0

即時使用角度1.3.15和它不會停止執行。 – 2015-07-14 17:38:26

1

你有兩個嵌套的指令:

  1. uiConfirm
  2. ngClick

你然後綁定了兩個事件處理它(一個由uiConfirm,另一個由ngClick)。 With preventDefault你想停止默認動作,但我猜測按鈕的默認動作是不調用動作()方法。 stopPropagation只是防止事件從冒泡了DOM樹,但既然你只關心按鈕本身它不會改變任何東西。

我會做的是在指令中創建一個自定義動作方法,然後檢查它是否應該做某件事。

.directive('uiConfirm', function() 
{ 
    return { 
     restrict: 'A', 
     link: function(scope, element, attrs) 
     { 
      scope.action = function(){ 
       // Check whether there is something to do or not. 
      }; 
     } 
    } 
}) 
+0

讓我們假設,而不是ng:click,我創建了ui:確認這將是ng:click和previous ui:confirm的混合。但是,我怎麼才能從指令中評估我已經傳入指令的函數呢? ui:confirm =「action()」 - >在指令中它是一個簡單的字符串,而不是一個函數。 – 2013-03-13 18:11:47

+1

@maximkott,'scope。$ eval(attrs.uiConfirm)'。 – 2013-03-13 19:18:17

+0

@MarkRajcok會嘗試這個,稍後發佈你的結果) – 2013-03-14 20:53:39