Yii,ajax,Button。如何防止多个JS onclick绑定

时间:2011-02-18 09:17:07

标签: ajax yii

(首先,英语不是我的母语,如果我可能会弄错的话,我很抱歉)。 我创建了Yii Web应用程序,主页上的输入表单是在按钮点击ajax请求后出现的。表单上有一个“取消”按钮,使div与表单不可见。如果我单击“显示表单”和“取消”N次,然后提交包含数据的表单,请求将重复N次。显然,浏览器会在每次出现表单时将onclick事件绑定到提交按钮。任何人都可以解释如何预防吗? 谢谢!

6 个答案:

答案 0 :(得分:3)

我遇到了完全相同的问题,并在Yii Forum进行了讨论。

这基本上是因为您可能使用“ render()”而不是 renderPartial()返回ajax结果。这会每次添加javascript代码以激活所有ajax按钮。如果他们已经活跃,他们现在将被触发两次。所以解决方案是使用 renderPartial()。要么只使用第一次渲染,然后使用 renderPartial(),要么从头开始使用 renderPartial(),但要确保“ processOutput ”参数仅在第一次设置为TRUE。

答案 1 :(得分:2)

解决! 有两个步骤: 第一。我决定将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);
");

希望它会对某人有所帮助。

答案 2 :(得分:1)

我遇到了同样的问题,修复工具在以“ 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'的标签id添加到Yii生成的按钮中,因此我可以使用jQuery undelegate()函数来定位它。

答案 3 :(得分:0)

我在这个项目中以这种方式解决了这个问题,它可能不是一个好方法,但对我来说工作正常:我只是在ajax属性中添加了唯一的'id'(在我的情况下像smth一样

                <?=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()))
                     ?>

)。 当然,您应该使用属性' processOutput '= true来调用 renderPartial 。在那之后,一切都运行良好,因为每个新元素只有一个绑定的js-action。

答案 4 :(得分:0)

下面的文字从http://www.yiiframework.com/forum/index.php/topic/14562-ajaxsubmitbutton-submit-multiple-times-problem/

复制而来
  

常见问题......

     如果你有多个,那么aj ajax东西不能正常工作,如果   你没有设置唯一ID

     

你应该确保每次都有唯一的ID ...

     

你应该知道,如果你通过ajax加载表单 - yii不工作   好吧,因为它在javascript代码中有一些错误,有死   并且活着

答案 5 :(得分:0)

在我看来你应该使用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>

之后,当必须在页面上显示每个元素时,您不必绑定和解除绑定。此外,这个解决方案操作简单,它的代码清洁。这也很容易在代码中找到和修改。

我希望,这可能对某人有用。

问候
。西蒙