Как предотвратить двойные щелчки с помощью ember.js?

Я пытаюсь выяснить идиоматический способ предотвратить многократное нажатие кнопки.

Представьте, что у меня есть простое действие контроллера, например...

var FooController = Ember.ObjectController.extend({
  actions: {
    go: function() {
        console.log("done!");
    }
  }
});

и в моем шаблоне у меня есть кнопка, определенная так...

<button {{action go}}>Click Me Fast</button>

Есть ли у действия возможность отключить его немедленно/сделать так, чтобы только один раз истинное событие было обработано контроллером (например, пока оно не будет отключено)

Изменить

Я ищу долгосрочное / многоцелевое решение. Одна идея, о которой я думаю, - это создание специального ember-компонента под названием «button-disable», который позволил бы мне создать настраиваемый тип кнопки, который обычно отключается после одного щелчка, но все же позволит мне передавать события родителю. контроллер. Это кажется немного тяжелее, чем мне хотелось бы, поэтому, если существует другой вариант, или если кто-то создал дополнение только для этого - дайте мне знать


person Toran Billups    schedule 24.11.2014    source источник
comment
Может быть, это то, что вам нужно. github.com/dockyard/ember-cli-async-button   -  person blessenm    schedule 25.11.2014


Ответы (1)


В качестве одноразового, если вы привяжете отключенный атрибут к своей кнопке, например, так

<button {{action go}} {{bind-attr disabled=actionPerformed}}>

а затем настройте свой контроллер, как

var FooController = Ember.ObjectController.extend({
    actionPerformed: false,
    actions: {
      go: function() {
        this.set("actionPerformed", true);
        console.log("done!");
    }
  }
}); 

тогда кнопка станет неактивной после того, как вы нажмете ее один раз

Если вам нужен повторно используемый компонент, я бы позаимствовал кнопку счетчика с http://emberjs.com/guides/cookbook/helpers_and_components/spin_button_for_asynchronous_actions/ и настройте его по своему усмотрению.

Таким образом, ваш JS будет соответствовать

window.SpinEg = Ember.Application.create({});

SpinEg.ApplicationController = Ember.Controller.extend({
    isLoading:false,
  buttonText:"Submit",
    actions:{
        saveData:function(){
            var self = this;
            var saveTime = Ember.run.later(function(){
                self.set('isLoading', false);

            }, 1000);
        }
    }
});

SpinEg.SpinButtonComponent = Ember.Component.extend({
    classNames: ['button'],
  buttonText:"Save",
    isLoading:false,
    actions:{
        showLoading:function(){
            if(!this.get('isLoading')){
                this.set('isLoading', true);
                this.sendAction('action');
            }
        }
    }
});

Шаблон для вашего компонента будет

<script type='text/x-handlebars' id='components/spin-button'>
    <button {{bind-attr id=id}} {{action 'showLoading'}}>
        {{#if isLoading}}
            <img src="http://i639.photobucket.com/albums/uu116/pksjce/spiffygif_18x18.gif"></img>
        {{else}}
            {{buttonText}}
        {{/if}}
    </button>
</script>

и вы бы просто включили следующее, где вам нужна кнопка, чтобы появиться

<script type='text/x-handlebars' id='application'>
    {{spin-button id="forapplication" isLoading = isLoading buttonText=buttonText  action='saveData'}}
</script>
person Ruaidhrí Primrose    schedule 24.11.2014
comment
прямо - см. редактирование выше (я ищу многоразовое решение, которое может охватывать множество кнопок в большом проекте) - person Toran Billups; 24.11.2014
comment
А, вы добавили свое редактирование одновременно с тем, как я опубликовал :) Я отредактировал свой ответ, упомянув компонент кнопки-спиннера из кулинарной книги Ember. В основном он делает то, что вы хотите, действие будет отправляться только тогда, когда свойство isLoading имеет значение false. - person Ruaidhrí Primrose; 24.11.2014
comment
Что не так с переносом этого решения в компонент Ember? - person givanse; 24.11.2014
comment
Спасибо за подробное объяснение! - person Toran Billups; 24.11.2014