2013-04-25 89 views
20

是有可能NG單擊寫一個攔截器的NG-點擊? 我有一個按鈕或一個鏈接,導致在後端刪除一個對象。我想通過添加一個屬性到按鈕/鏈接來確認對話框(模態)。例如: -攔截angularJS

<a href="#" ng-click="deleteIt(id)" confirmation-needed>Delete</a> 

這可能與AngularJS?有沒有更好的方法解決這個問題?

EDIT的deleteIt方法駐留在不同的控制器。

THX

回答

49

我已經把一個例子指令中:

http://plnkr.co/edit/GJwK7ldGa9LY90bMuOfl?p=preview

我通過創建一個指令實現它:

  1. ngClick更高priority,以便它能夠ngClick之前調用,
  2. 使得該terminal所以它不叫ngClick
  3. 聽單擊事件,然後評估ngClick值,如果消息是確定的。

作爲獎勵,你可以通過在自己的消息,如:

<a href="#" ng-click="deleteIt(id)" 
    confirmation-needed="Really Delete?" 
     >Delete with custom message</a> 

的代碼看起來是這樣的:

app.directive('confirmationNeeded', function() { 
    return { 
    priority: 1, 
    terminal: true, 
    link: function (scope, element, attr) { 
     var msg = attr.confirmationNeeded || "Are you sure?"; 
     var clickAction = attr.ngClick; 
     element.bind('click',function() { 
     if (window.confirm(msg)) { 
      scope.$eval(clickAction) 
     } 
     }); 
    } 
    }; 
}); 

希望有所幫助。

+0

非常好,這是我尋找的解決方案,謝謝! – Soccertrash 2013-04-25 11:22:57

+0

這很接近我怎麼也做到了。但是,這裏是另一個工作非常相似,除非它不關心你是否有一個ng-click或不。 http://plnkr.co/edit/Cwu15Z8U6ok0MMF8p6Ks?p = preview – ganaraj 2013-04-25 12:27:05

+1

@ganaraj:當我單擊取消時,這不起作用,因爲JQLite的'createEventHandler'繼續遍歷所有綁定的事件,並且不會停止第二個'bind('click',... )'被叫。 (我的瀏覽器:Mac OSX 10.6.8上的Chrome版本26.0.1410.65) – Piran 2013-04-26 10:02:49

3

你可以注入$window到您的控制器,這樣就可以使用$window.confirm從 你的範圍,那麼:

<a href="#" ng-click="confirm('message') && deleteIt(id)">Delete</a> 
+0

謝謝,@tosh!這使我需要做的事情走上正確的軌道。我在下面發佈了另一個答案,它採用了相同的概念,但將它與指令相結合,因此我可以自定義我的確認對話框。 – Dustin 2014-05-17 04:15:31

10

我已經放棄了皮蘭得到的答覆工作,我想它。相反,我一開始只是我自己的指令替換ngClick:

.directive('confirmClick', function() { 
    return { 
     restrict: 'A', 
     link: function(scope, elt, attrs) { 
      elt.bind('click', function(e) { 
       var message = attrs.confirmation || "Are you sure you want to do that?"; 
       if (window.confirm(message)) { 
        var action = attrs.confirmClick; 
        if (action) 
         scope.$apply(scope.$eval(action)); 
       } 
      }); 
     }, 
    }; 
}) 

該指令,甚至沒有自己的範圍,從而簡化了與其他指令顯著結合它。它從attrs直接獲取所需的一切。它使用像這樣:

<span ng-show="editing" confirm-click="delete()" confirmation="delete confirmation message goes here">some text</span> 

delete()功能必須存在較高處的$scope鏈。我相信這可以通過仔細研究ng-click的實施情況來改善,但我還沒有得到它!

+0

$ apply($ eval())仍然需要嗎?似乎只用$ apply(action)就可以工作。 – Priit 2015-04-17 13:21:26

+1

嗯...自從我寫這篇文章以來已經有一段時間了...我猜你不需要兩者都可以! – samson 2015-04-20 04:47:45

5

我打這個很長一段時間,但角的異步性質使得我們很難對每一個指令打起來很好算。然後,我看到@託什的回答,這讓我思考。

我認爲這將幾個優點:創建指令和前置ngClick

所以,只要這個指令添加到您的應用程序,然後添加「確認單擊」屬性您的鏈接,以及confirmClick()函數給你的ngClick。

鏈接:

<a href="#" ng-click="confirmClick() && deleteIt(id)" confirm-click>Delete</a> 

指令:

.directive('confirmClick', function() { 
    return { 
     link: function (scope, element, attrs) { 
      // setup a confirmation action on the scope 
      scope.confirmClick = function(msg) { 
       // msg can be passed directly to confirmClick('are you sure?') in ng-click 
       // or through the confirm-click attribute on the <a confirm-click="Are you sure?"></a> 
       msg = msg || attrs.confirmClick || 'Are you sure?'; 
       // return true/false to continue/stop the ng-click 
       return confirm(msg); 
      } 
     } 
    } 
}) 

這是非常相似的注射標準的confirm()對話框,而是因爲你的指令,擁有它,你可以自定義你如何選擇運行你的確認對話框(可能是一個漂亮的模式,而不是一個窗口對話框)。

**** BONUS ANSWER ****

我打了這個越來越一體化,使用模態窗口的確認,而不是默認的窗口的解決方案。以下是完整的解決方案:https://stackoverflow.com/a/23718694/1135826