2012-04-24 65 views
14

什麼是最好的方法來禁用一個按鈕,所以雙擊不會發生與knockout.js。我有一些用戶做一些快速點擊導致多個Ajax請求。我認爲knockout.js可以通過多種方式處理這個問題,並希望看到一些替代方案。防止雙擊一個按鈕與knockout.js

回答

13

使用信號量(旋轉鎖)。基本上,您可以計算某個元素註冊的點擊次數,如果該值超過1,則返回false,並且不允許進行以下點擊。可以使用超時功能來清除鎖定,以便在5秒鐘後再次點擊。你可以從http://knockoutjs.com/documentation/click-binding.html

修改的例子如這裏看到:

<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> 

通過改變嵌套函數內部的邏輯來

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

偉大的答案!這也可以重構爲自定義點擊綁定。 – madcapnmckay 2012-04-24 22:53:28

+0

完美答案。我繼續前進,將所有的電話都打包完畢,並且在每次ajax呼叫之後重置點擊次數,當然一般。我想知道自定義綁定的樣子。 – 2012-04-24 23:47:22

10

我遇到了一個表單嚮導提交數據類似的問題通過Ajax點擊按鈕。每一步我們都有4個按鈕可選擇顯示。我們創建了一個布爾型可觀察值ButtonLock,並且如果它是真的,則從提交函數返回。那麼我們也數據綁定每個按鈕的disableButtonLock觀察到

視圖模型:

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

按鈕:

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

如果你只是需要防止多次點擊,我更喜歡布爾。但是,如果您需要該功能,則計數器方法可讓您檢測到雙擊並單獨處理它們。

+4

我更喜歡這個答案。它爲用戶提供了一些關於正在發生的事情與計數方法的視覺指示器。用戶可以反覆點擊該按鈕,並且沒有指示器發生了什麼,所以他們可能會認爲某些事情已經破裂。 – MorganTiley 2012-08-28 14:55:05

+0

我同意@MorganTiley,這是一個更好的解決方案 – 2014-05-18 18:25:53

4

如果有人仍在尋找辦法做到這一點。我發現你可以使用布爾值。

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

然後在您的視圖

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

我有一個自定義綁定這樣做:

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