我正在我的提交按钮上创建一个加载指示器,并使用 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-pjax
至 2.0.6
.这使得第 3) 点不再必要,并且使第 2) 点不那么重要,尽管知道它仍然是一件好事。
关于javascript - Yii2 Pjax 和 ActiveForm beforeSubmit 在重新加载后不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29524980/