2013-04-25 20 views
20

là nó có thể viết một interceptor cho ng-click? Tôi có một nút hoặc một liên kết dẫn đến việc xóa một đối tượng trong phần phụ trợ. Tôi muốn có một hộp thoại xác nhận (phương thức) bằng cách thêm một thuộc tính vào nút/liên kết. Ví dụ:Ngăn chặn ng-click trong angularJS

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

Điều này có thể thực hiện với AngularJS không? Có cách nào tốt hơn để giải quyết vấn đề này?

EDIT Phương thức deleteIt nằm trong các bộ điều khiển khác nhau.

Thx

Trả lời

49

Tôi đã đặt một chỉ dụ trong:

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

Tôi đạt được điều đó bằng cách tạo chỉ thị:

  1. với một priority cao hơn ngClick, vì vậy mà nó được gọi trước khi ngClick,
  2. làm mà terminal để nó không gọi ngClick.
  3. nghe sự kiện nhấp và sau đó đánh giá giá trị ngClick nếu thông báo là ok.

Như một phần thưởng, bạn có thể vượt qua trong thông điệp của riêng bạn, chẳng hạn như:

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

Mã này trông như thế này:

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) 
     } 
     }); 
    } 
    }; 
}); 

Hy vọng rằng sẽ giúp.

+0

Rất đẹp, đây là giải pháp tôi đã tìm kiếm, cảm ơn! – Soccertrash

+0

Đây là cách tôi đã làm nó quá .. Nhưng, đây là một plunk hoạt động khá nhiều giống nhau ngoại trừ nó không quan tâm cho dù bạn có một ng-click hay không .. http://plnkr.co/edit/Cwu15Z8U6ok0MMF8p6Ks? P = xem trước – ganaraj

+1

@ganaraj: Điều đó không có tác dụng khi tôi nhấn Cancel, bởi vì 'createEventHandler' của JQLite tiếp tục lặp qua tất cả các sự kiện bị ràng buộc, và không dừng lần thứ hai' bind ('click', ...) 'khỏi bị gọi. (Trình duyệt của tôi: Phiên bản Chrome 26.0.1410.65 trên Mac OSX 10.6.8) – Piran

3

Bạn có thể tiêm $window vào điều khiển của bạn để bạn có thể sử dụng $window.confirm từ phạm vi của bạn, sau đó:

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

Cảm ơn, @tosh! Điều này đặt tôi đi đúng hướng cho những gì tôi cần làm. Tôi đăng một câu trả lời dưới đây có cùng một khái niệm nhưng cặp vợ chồng nó với một chỉ thị, vì vậy tôi có thể tùy chỉnh hộp thoại xác nhận của tôi. – Dustin

10

Tôi đã từ bỏ việc nhận được câu trả lời của Piran để làm việc như tôi muốn. Thay vào đó, tôi đã bắt đầu thay thế ngClick bằng chỉ thị của riêng tôi:

.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)); 
       } 
      }); 
     }, 
    }; 
}) 

Chỉ thị này thậm chí không có phạm vi riêng, giúp đơn giản hóa việc kết hợp nó với các chỉ thị khác một cách đáng kể. Nó có mọi thứ cần thiết trực tiếp từ attrs. Nó được sử dụng như sau:

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

Chức năng delete() phải tồn tại ở đâu đó cao hơn trong chuỗi $scope. Tôi chắc chắn điều này có thể được cải thiện bằng cách xem xét kỹ hơn cách thức ng-click được triển khai, nhưng tôi vẫn chưa thực hiện được!

+0

Có phải $ apply ($ eval()) vẫn cần thiết không? Dường như làm việc tốt với chỉ $ áp dụng (hành động). – Priit

+1

Hmm ... Đã lâu rồi kể từ khi tôi viết bài này ... Tôi đoán bạn không cần cả hai! – samson

5

Tôi đã chơi trò chơi này trong một thời gian dài, nhưng bản chất không đồng bộ của Angular khiến mọi người khó có thể tin tưởng vào mọi chỉ thị chơi độc đáo cùng nhau. Sau đó, tôi thấy câu trả lời của @ tosh, điều đó khiến tôi suy nghĩ.

Tôi nghĩ rằng đây kết hợp nhiều ưu điểm: Tạo một Chỉ thị và Thêm vào trước ngClick

Vì vậy, chỉ cần thêm chỉ thị này để ứng dụng của bạn, và sau đó thêm các "xác nhận chuột" thuộc tính liên kết của bạn, cũng như hàm confirmClick() cho ngClick của bạn.

Link:

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

Chỉ thị:

.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); 
      } 
     } 
    } 
}) 

này rất giống với tiêm xác nhận tiêu chuẩn() hộp thoại, nhưng vì bạn có nó trong một chỉ thị, bạn có thể tùy chỉnh cách bạn chọn để chạy hộp thoại xác nhận của bạn (có thể là một kiểu khá, thay vì hộp thoại cửa sổ).

**** THƯỞNG ĐÁP ****

tôi đã chơi với hơn này và tích hợp một giải pháp mà sử dụng một cửa sổ modal như thư xác nhận, chứ không phải là cửa sổ mặc định. Đây là giải pháp hoàn chỉnh: https://stackoverflow.com/a/23718694/1135826