2012-04-24 66 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); 
     }) 
    } 
}