Yii, AJAX, Баттон. Как предотвратить множественные привязки JS onclick - PullRequest
3 голосов
/ 18 февраля 2011

(Прежде всего английский не мой родной язык, извините, если я, вероятно, ошибаюсь).Я создал веб-приложение Yii, где на главной странице есть форма ввода, которая появляется после нажатия кнопки через запрос ajax.В форме есть кнопка «Отмена», которая делает div с формой невидимым.Если я нажимаю «Показать форму» и «Отмена» N раз, а затем отправляю форму с данными, запрос повторяется N раз.Очевидно, что браузер связывает событие onclick с кнопкой отправки каждый раз, когда появляется форма.Кто-нибудь может объяснить, как это предотвратить?Спасибо!

Ответы [ 6 ]

3 голосов
/ 18 февраля 2011

У меня была точно такая же проблема, и на форуме Yii .

обсуждалась эта проблема. В основном это происходит потому, что вы, вероятно, возвращаете результаты ajax с "render ()"вместо или renderPartial () .Это добавляет код JavaScript каждый раз, чтобы активировать все кнопки AJAX.Если они уже были активны, они будут активированы дважды.Поэтому решение состоит в том, чтобы использовать renderPartial () .Либо используйте render только в первый раз, а затем renderPartial () , либо используйте renderPartial () с самого начала, но убедитесь, что параметр " processOutput " установлен толькоИСТИНА в первый раз.

2 голосов
/ 21 февраля 2011

Решено!Было два шага: первый.Я решил добавить код JS в мой экземпляр CHtml :: ajaxSubmitButton, который отменяет привязку события onclick к этой самой кнопке после нажатия.Нет успеха!Вернуться к работе.После двух часов копания я понял, что когда вы нажимаете кнопку «Отправить», возникает не только событие «щелкнуть».Это также вызывает событие «отправить».Так что вам нужно отменить привязку любого события ко всей форме, а не только к кнопке!Вот мой код:

echo CHtml::submitButton($diary->isNewRecord ? 'Создать' : 'Сохранить', array('id' => 'newRecSubmit'));
Yii::app()->clientScript->registerScript('btnNewRec', "
    var clickNewRec = function()
    {
        jQuery.ajax({
            'success': function(data) {
                $('#ui-tabs-1').empty();
                $('#ui-tabs-1').append(data);
            },
            'type': 'POST',
            'url': '".$this->createUrl('/diary/newRecord')."',
            'cache': false,
            'data': jQuery(this).parents('form').serialize()
        });

        $('#new-rec-form').unbind();

        return false;
    }

    $('#newRecSubmit').unbind('click').click(clickNewRec);
");

Надеюсь, это кому-нибудь поможет.

1 голос
/ 28 сентября 2012

Я просто столкнулся с той же проблемой, исправление находится в строке, которая начинается с ' beforeSend '. Функция jQuery undelegate () удаляет обработчик из события для всех элементов, которые соответствуют текущему селектору.

<?php echo CHtml::ajaxSubmitButton(
  $model->isNewRecord ? 'Add week(s)' : 'Save',
  array('buckets/create/'.$other['id'].'/'.$other['type']),
  array(
    'update'=>'#addWeek',
    'type'=>'POST',
    'dataType'=>'json',
    'beforeSend'=>'function(){$("body").undelegate("#addWeeksAjax","click");}',
    'success'=>'js:function(data) {
      var a=[];
     }',
  ),
  array('id'=>'addWeeksAjax')
); ?>

В моем примере я добавил идентификатор тега со значением 'addWeeksAjax' к кнопке, сгенерированной Yii, чтобы я мог назначить ее функцией jQuery undelegate () .

0 голосов
/ 17 августа 2013

На мой взгляд, вы должны использовать функцию jQuery.on. Это вызовет событие для динамически изменяемого контента. Например: вы загружаете некоторый список изображений и заполняете их на сайте новыми кнопками управления (просмотр, редактирование, удаление). Пример структуры может выглядеть так:

<div id="img_35" class='img-layer'>
   <img src='path.jpg'>
   <button class='view' ... />
   <button class='edit' ... />
   <button class='delete' ... />
</div>

Тогда правильный JS может выглядеть следующим образом (только для удаления, другие похожи):

<script type="text/javascript">
    $(document).on('click', '.img-layer .delete', function() {
        var imgId = String($(this).parent().attr('id)).split('_')[1]; //obtain img ID
        $.ajax({
           url: 'http://www.some.ajax/url',
           type : 'POST',
           data: {
               id: imgId
           }
        }).done({
            alert('Success!');
        }).fail({
            alert('fail :(');
        });
    }
</script>

После этого вам не нужно связывать и откреплять каждый элемент, когда он должен появиться на вашей странице. Кроме того, это решение простое и чистое. Это также легко найти и изменить в коде.

Надеюсь, кому-то это может пригодиться.

Привет
, Simon

0 голосов
/ 04 сентября 2012

текст ниже скопирован отсюда http://www.yiiframework.com/forum/index.php/topic/14562-ajaxsubmitbutton-submit-multiple-times-problem/

общая проблема ...

yii Ajax не работает должным образом, если у вас есть более одного, и если Вы не установили уникальный идентификатор

вы должны быть уверены, что все имеют уникальный идентификатор каждый раз ...

и вы должны знать, что если вы загружаете форму через ajax - yii не работает хорошо с этим, потому что у него есть некоторые ошибки в коде JavaScript, с умереть и живи

0 голосов
/ 21 марта 2012

Я решил эту проблему в своем проекте таким образом, это может быть не очень хорошим способом, но он отлично работает для меня: я просто добавил уникальный 'id' в свойства ajax (в моем случае что-то вроде

                <?=CHtml::ajaxLink('<i class="icon-trash"></i>',
                    $this->createUrl('afisha/DeletePlaceAjax',
                    array('id'=>$value['id'])),
                    array('update'=>'.data', 
                     'beforeSend' => 'function(){$(".table").addClass("loading");}',
                     'complete' => 'function(){$(".table").removeClass("loading");}'),
                   array('confirm'=>"Уверены?",'id'=>md5($value['id']).time()))
                     ?>

).Конечно, вы должны вызвать renderPartial со свойством ' processOutput ' = true.После этого все работает хорошо, потому что у каждого нового элемента есть только одно связанное js-действие.

...