2012-04-24 35 views
14

Cách tốt nhất để vô hiệu hóa nút để nhấp đúp không xảy ra với knockout.js là gì. Tôi có một số người dùng thực hiện một số thao tác nhấp nhanh gây ra nhiều yêu cầu ajax. Tôi cho rằng knockout.js có thể xử lý điều này theo nhiều cách và muốn xem một số giải pháp thay thế.Ngăn chặn nhấp đúp vào nút có knockout.js

Trả lời

13

Sử dụng semaphore (khóa kéo sợi). Về cơ bản, bạn tính số lượng nhấp chuột mà một phần tử đã đăng ký và nếu nhiều hơn 1 bạn trả về false và không cho phép các nhấp chuột sau đây. Bạn có thể sử dụng chức năng hết thời gian chờ để xóa khóa để có thể nhấp lại sau khi nói, 5 giây. Bạn có thể sửa đổi các ví dụ từ http://knockoutjs.com/documentation/click-binding.html

Như đã thấy ở đây:

<div> 
You've clicked <span data-bind="text: numberOfClicks"></span> times 
<button data-bind="click: incrementClickCounter">Click me</button> 
</div> 

<script type="text/javascript"> 
var viewModel = { 
    numberOfClicks : ko.observable(0), 
    incrementClickCounter : function() { 
     var previousCount = this.numberOfClicks(); 
     this.numberOfClicks(previousCount + 1); 
    } 
}; 
</script> 

Bằng cách thay đổi logic bên trong hàm lồng nhau để

if(this.numberOfClicks() > 1){ 
//TODO: Handle multiple clicks or simply return false 
// and perhaps implement a timeout which clears the lockout 
} 
+0

Great câu trả lời! Điều này cũng có thể được tái cấu trúc thành một liên kết nhấp chuột tùy chỉnh. – madcapnmckay

+0

Câu trả lời hoàn hảo. Tôi đã đi trước và gói tất cả các cuộc gọi của tôi trong đó mà không có vấn đề, và thiết lập lại các nhấp chuột sau mỗi cuộc gọi ajax, nói chung tất nhiên. Tôi tự hỏi làm thế nào một ràng buộc tùy chỉnh có thể giống như thế. –

10

Tôi chạy vào một vấn đề tương tự với một dữ liệu dạng thuật sĩ trình qua Ajax khi nhấp vào nút. Chúng tôi có 4 nút có thể nhìn thấy có chọn lọc cho mỗi bước. Chúng tôi đã tạo ra một boolean có thể quan sát được ButtonLock và được trả về từ chức năng gửi nếu nó đúng. Sau đó, chúng tôi cũng dữ liệu ràng buộc các disable của mỗi nút đến ButtonLock thể quan sát được

ViewModel:

var viewModel = function(...) { 
    self.ButtonLock = ko.observable(false); 

    self.AdvanceStep = function (action) { 
     self.ButtonLock(true); 
     // Do stuff 
     // Ajax call 
    } 

    self.AjaxCallback = function(data) { 
     // Handle response, update UI 
     self.ButtonLock(false); 
    } 

Button:

<input type="button" id="FormContinue" name="FormContinue" class="ActionButton ContinueButton" 
    data-bind=" 
     if: CurrentStep().actions.continueAction, 
     disable: ButtonLock, 
     value: CurrentStep().actions.continueAction.buttonText, 
     click: function() { 
      AdvanceStep(CurrentStep().actions.continueAction); 
     }"/> 

Nếu bạn chỉ cần để ngăn chặn nhiều lần nhấp chuột, tôi thích boolean . Nhưng phương pháp truy cập cho phép bạn phát hiện các nhấp chuột đôi và xử lý chúng một cách riêng biệt, nếu bạn muốn tính năng đó.

+4

Tôi thích câu trả lời này nhiều hơn. Nó cung cấp cho người dùng một số chỉ báo trực quan về những gì đang xảy ra so với cách tiếp cận đếm. Người dùng có thể nhấp vào nút nhiều lần và không có chỉ báo những gì đang xảy ra để họ có thể nghĩ rằng điều gì đó đã xảy ra. – MorganTiley

+0

Tôi đồng ý với @MorganTiley, đây là giải pháp tốt hơn –

4

Trong trường hợp bất kỳ ai vẫn đang tìm cách để thực hiện việc này. Tôi thấy rằng bạn có thể sử dụng boolean.

self.disableSubmitButton= ko.observable(false); 
    self.SubmitPayment = function() { 
     self.disableSubmitButton(true); 
     //your other actions here 
     } 

Sau đó, theo quan điểm của bạn

data-bind="click:SubmitPayment, disable:disableSubmitButton" 
0

Tôi đã làm điều này với ràng buộc một tùy chỉnh:

<button data-bind="throttleClick: function() { console.log(new Date()); }> 
    I wont double click quicker than 800ms 
</button> 

ko.bindingHandlers.throttleClick = { 
    init: function(element, valueAccessor) { 
     var preventClick = false; 
     var handler = ko.unwrap(valueAccessor()); 

     $(element).click(function() { 
      if(preventClick) 
       return; 

      preventClick = true; 
      handler.call(); 
      setTimeout(function() { preventClick = false; }, 800); 
     }) 
    } 
} 
Các vấn đề liên quan