2012-04-24 6 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

+0

完璧な答え。私は先に進み、問題なしですべての呼び出しをラップし、一般的にはもちろん、それぞれのajax呼び出しの後にクリックをリセットします。カスタムバインディングがどのように見えるのだろうか。 –

10

にネストされた関数の内部ロジックを変更することによりAjax経由でボタンをクリックします。各ステップごとに4つのボタンが選択的に表示されます。ブール値観測値ButtonLockを作成し、それが真であれば提出関数から戻しました。その後、我々はまた、データバインド各ボタンのdisableButtonLock観測可能

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

ボタン:あなただけの複数のクリックを防ぐために必要がある場合は

<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

+0

私は@MorganTileyに同意します。これはより良い解決策です –

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); 
     }) 
    } 
} 
関連する問題