Yii2 Pjax和ActiveForm重装后beforeSubmit无法正常工作吗? [英] Yii2 Pjax and ActiveForm beforeSubmit not working after reload?

查看:54
本文介绍了Yii2 Pjax和ActiveForm重装后beforeSubmit无法正常工作吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am creating a loading indicator on my submit button and attaching the "start" procedure to the beforeSubmit event using the registerJs function.

第一次运行正常,但是重新加载Pjax容器后,再次提交表单时不会触发该事件.

It works properly the first time, but after the Pjax container is reloaded, the event won't fire when the form is submitted again.

我将整个视图文件封装在Pjax容器中,以便正确显示Flash消息.

I am enclosing the entire view file in the Pjax container so that the flash messages are properly displayed.

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

Here is the main.php layout file snippet:

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

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

<?= $content; ?>

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

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

And here is the registerJs function, located in main.php in the section:

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

这是activeForm:

And here is the 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小部件(详细信息和演示)

I am using the Kartik Spinner Widget (Details and Demo)

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

Any ideas on why the beforeSubmit event won't fire after Pjax has loaded the data container after a successful for submit?

谢谢.

推荐答案

出现此问题有多种原因.

This problem occurs for several reasons.

首先,放置在 $(document).ready(); 中并加载到称为页面(包含页面)的ajax中的任何代码在加载后将不会执行.

Firstly, Any code placed within $(document).ready(); and loaded on the ajax called page (contained page) will not be executed after it is loaded.

其次,不保证对外部脚本(< script src> )的任何引用会在内联脚本之前加载.对于Yii2,这些内联脚本将使用 registerJs()

Secondly, any references to external scripts (<script src>) aren't guarantied to load before inline scripts. In the case of Yii2 these inline scripts would be registered with registerJs()

让Pjax在与脚本相关的复杂页面进行加载时表现不错,这不是很简单.

Getting Pjax to play nice with complex script dependent pages to load is not trivial.

一些解决您问题的方法:

A few things to solve your issues:

1)内联脚本,该内联脚本装有 registerJs(),并且其位置设置为 POS_READY (默认值)?如果视图是通过 render()呈现的,则为code> $(document).ready().

1) Inline scripts loaded with registerJs() and set with a position of POS_READY (default?) will be contained within a $(document).ready() if the view is rendered via render().

因此,重要的是通过 renderAjax()进行渲染.这样可以确保内联脚本能够运行.

Thus it is important to render via renderAjax(). This will ensure that the inline scripts will run.

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

Sometimes (most times) you will need to use render() when statically loaded and renderAjax() when pjax loads a page. In your instance this is required in order to place the Pjax widget in the layout. You can use the following code for these situations:

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

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

2) When writing external scripts that you know will load within the context of a pjax call. Use:

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

这将正确加载脚本.但是请记住,每次Pjax调用成功时,它将重新加载/重新绑定脚本.不幸的是,这可能不是所希望的.

This will load the script correctly. But keep in mind that it will reload/rebind the script every time a Pjax call succeeds. That might not be desired unfortunately.

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

Also keep in mind that the pjax:success event does not necessarily fire after the external scripts from the contained page are loaded. See 3)

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

3) To solve script order issues you will need to remove the following line from the pjax.js script:

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

但是,这将对设置为禁用 eval()的浏览器造成问题(因此该行排在第一位)

This will however create issues with browsers that are set to disable eval() (hence why the line exists in the first place)

Pjax最终将进行排序.您可以在此处

Pjax will eventualy have this sorted. You can keep track of the progress here

如果不清楚,请告诉我,我会改写.

If anything is unclear let me know and I'll rephrase.

更新:Yii 2.0.7进行了更改.其中之一是将 bower \ yii2-pjax 更新为 2.0.6 .这使要点 3)不再必要,并使要点 2)不再重要,尽管这仍然是一件好事.

UPDATE: Yii 2.0.7 has introduced changes. One of which is updating the bower\yii2-pjaxto 2.0.6. This makes point 3) no longer necessary and makes point 2) less important, although it's still a good thing to know.

这篇关于Yii2 Pjax和ActiveForm重装后beforeSubmit无法正常工作吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆