javascript - Yii2 Pjax 和 ActiveForm beforeSubmit 在重新加载后不起作用?

标签 javascript yii2 pjax

我正在我的提交按钮上创建一个加载指示器,并使用 registerJs 函数将“开始”过程附加到 beforeSubmit 事件。

第一次可以正常工作,但是重新加载Pjax容器后,再次提交表单时不会触发该事件。

我将整个 View 文件封装在 Pjax 容器中,以便正确显示 flash 消息。

这是 main.php 布局文件片段:

<?php Pjax::begin([
'id' => 'pjax-container',
'enablePushState' => false,
]); ?>

<?= Alert::widget(); ?>

<?= $content; ?>

<?php Pjax::end(); ?>

这是 registerJs 函数,位于 main.php 中的部分:

<?php
$js = <<< 'SCRIPT'
$('#form').on('beforeSubmit', function(){
alert('Submitted...');
//$("#spinner").fadeIn();
});
SCRIPT;
$this->registerJs($js);
?>

这里是 activeForm:

<?php $form = ActiveForm::begin(['id' => 'form', 'options' => ['data-pjax' => true]]); ?>

<?= $form->field($model, 'name')->textInput(['type' => 'text']) ?>

<?= $form->field($model, 'email')->textInput(['type' => 'email']) ?>

<?= $form->field($model, 'subject')->textInput(['type' => 'text']) ?>

<?php
echo $form->field($model, 'message')->textArea(['rows' => 6]);

echo $form->field($model, 'verify_code')->widget(Captcha::className(), [
        'captchaAction' => 'site/captcha',
        'template' => '<div class="row"><div class="col-lg-4">{image}</div><div class="col-lg-6">{input}</div></div>',
]);
?>

<button class="btn btn-success">
<span id="spinner" style="display: none; float:left; margin-right: 26px;">
<?php
echo Spinner::widget([
'pluginOptions' => [
    'top' => '50%',
    'left' => '10px',
    'lines' => 11,
    'length' => 5,
    'width' => 3,
    'corners' => 1,
    'trail' => 100,
    'speed' => 1.25,
    'radius' => 4,
],
]);
?>
</span>
<?php echo $model->isNewRecord ? 'Send Message' : 'Update'; ?>
</button>

<?php ActiveForm::end(); ?>

我正在使用 Kartik Spinner Widget (Details and Demo)

关于为什么在成功提交后 Pjax 加载数据容器后 beforeSubmit 事件不会触发的任何想法?

谢谢。

最佳答案

出现此问题的原因有多种。

首先,$(document).ready(); 中的任何代码并加载到ajax调用的页面(contained page)上,加载完成后不会执行。

其次,任何对外部脚本 (<script src>) 的引用都不能保证在内联脚本之前加载。在 Yii2 的情况下,这些内联脚本将使用 registerJs() 注册。

让 Pjax 很好地处理复杂的脚本依赖页面以加载并非微不足道。

解决您问题的几件事:

1) 使用 registerJs() 加载的内联脚本并设置位置 POS_READY (默认?)将包含在 $(document).ready() 中如果 View 是通过 render() 呈现的.

因此通过 renderAjax() 渲染很重要.这将确保内联脚本运行。

有时(大多数时候)您需要使用 render()当静态加载和 renderAjax()当 pjax 加载页面时。在您的实例中,这是将 Pjax 小部件放置在布局中所必需的。对于这些情况,您可以使用以下代码:

if(Yii::$app->request->getHeaders()->has('X-PJAX'))
{
    return $this->renderAjax('myview');
}
else
{
    return $this->render('myview');
}

2) 在编写您知道将在 pjax 调用上下文中加载的外部脚本时。使用:

$(document).on('ready pjax:success', function(){
    // ...
});

这将正确加载脚本。但请记住,每次 Pjax 调用成功时,它都会重新加载/重新绑定(bind)脚本。不幸的是,这可能不是我们想要的。

另请记住 pjax:success加载包含页面的外部脚本后,事件不一定会触发。见 3)

3) 要解决脚本顺序问题,您需要从 pjax.js 脚本中删除以下行:

obj.scripts = findAll(obj.contents, 'script[src]').remove() 

然而,这会导致设置为禁用 eval() 的浏览器出现问题。 (因此为什么这条线首先存在)

Pjax 最终会对此进行排序。可以关注进度here

如果有任何不清楚的地方,请告诉我,我会重新措辞。

更新 Yii 2.0.7 引入了一些变化。其中之一是更新 bower\yii2-pjax2.0.6 .这使得第 3) 点不再必要,并且使第 2) 点不那么重要,尽管知道它仍然是一件好事。

关于javascript - Yii2 Pjax 和 ActiveForm beforeSubmit 在重新加载后不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29524980/

相关文章:

javascript - 当我重新加载页面时,jquery pjax 不工作。页眉其他男孩内容不见了

javascript - Reactjs : How to set navigator. geolocation.getCurrentPosition 在cookie中

javascript - 如何在没有 Web 服务器的情况下运行 ajax 代码?

javascript - 在ClojureScript中使用 'eval'特殊形式来判断一个形式是否是文字

jquery - 如何选择查询中的中间 3 位数字。我正在使用 yii2

php - 使用 Yii2 将 Android 表情符号从 Firebase 保存到 MySQL

validation - Yii2 - 如何在输入字段上添加自定义错误消息

javascript - 调用 REST API 会出现错误 TypeError

ajax - Yii2 Pjax GridView 操作按钮问题

django - django-pjax 应该如何处理重定向?