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 и вернулись из функции отправки, если это правда. Тогда мы также данные объять disable каждой кнопки на ButtonLock наблюдаемого

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); 
     }) 
    } 
} 
Смежные вопросы