Pjax JQuery插件
Pjax是一个小组件,它集成了pjax jQuery
插件。所有被这个小组件包括的内容,可以通过AJAX加载,而不需要刷新当前页面,这个小组件在你浏览器的地址栏中也使用HTML5 History API来修改当前URL。
准备
按照官方指南http://www.yiiframework.com/doc-2.0/guide-start-installation.html的描述,使用Composer包管理器创建一个新的应用。
如何做…
在下面的例子中,你可以看到如何通过yii\grid\GridView
小组件来使用Pjax:
<?php
use yii\widgets\Pjax;
?>
<?php Pjax::begin(); ?>
<?= GridView::widget([...]); ?>
<?php Pjax::end(); ?>
只需要在Pjax::begin()
和Pjax::end()
包裹任何代码片段。
这将会渲染出如下HTML代码:
<div id="w1">
<div id="w2" class="grid-view">...</div>
</div>
<script type="text/javascript">jQuery(document).ready(function () {
jQuery(document).pjax("#w1 a", "#w1", {...});
});</script>
所有被包裹的内容,包括翻页和排序链接,都会通过AJAX重新加载。
指定一个自定义ID
Pjax从AJAX请求获取页面内容,然后使用相同的ID释放它自己的DOM元素。你可以通过渲染没有布局的内容加速页面渲染性能,尤其是对于Pjax请求:
public function actionIndex()
{
$dataProvider = ...;
if (Yii::$app->request->isPjax) {
return $this->renderPartial('_items', [
'dataProvider' => $dataProvider,
]);
} else {
return $this->render('index', [
'dataProvider' => $dataProvider,
]);
}
}
默认情况下,yii\base\Widget::getId
方法会自增标识符,因此小组件在任何页面上,都会有一个自增的属性:
<nav id="w0">...</nav> // Main navigation
<ul id="w1">...</ul> // Breadcrumbs widget
<div id="w2">...</div> // Pjax widget
使用renderPartial()
或者renderAjax()
方法进行渲染,不需要渲染布局,你自己的页面将会有一个带有数字0的小组件:
<div id="w0">...</div> // Pjax widget
在这个结果中,你自己的小组件将不会在下次请求中通过w2
选择器找到自己的block。
但是,Pjax将会在Ajax响应中通过w2
选择器找到相同的block。在这个结果中,你自己的小组件将不会在下次请求中通过w2
选择器找到这个block。
因此,你必须为你的Pjax小组件手动指定一个唯一标识符,来避免冲突:
<?php Pjax::begin(['id' => 'countries']) ?>
<?= GridView::widget([...]); ?>
<?php Pjax::end() ?>
使用ActiveForm
默认情况下,Pjax只和被包裹的快交互。如果你想和ActiveForm
小组件一起使用它,你必须使用表单的data-pjax
选项:
<?php
use \yii\widgets\Pjax
use \yii\widgets\ActiveForm;
<?php yii\widgets\Pjax::begin(['id' => 'my-block']) ?>
<?php $form = ActiveForm::begin(['options' => [
'data-pjax' => true,
]]); ?>
<?= $form->field($model, 'name') ?>
<?php ActiveForm::end(); ?>
<?php Pjax::end(); ?>
它会为表单的提交事件添加相应的监听器。
你也可以使用Pjax小组件的$formSelector
选项,来指定什么表单提交将会出发pjax
。
使用客户端脚本
你可以订阅容器事件:
<?php $this->registerJs('
$("#my-block").on("pjax:complete", function() {
alert('Pjax is completed');
});
'); ?>
或者,你可以通过使用它的选择器,手动重新加载容器:
<?php $this->registerJs('
$("#my-button").on("click", function() {
$.pjax.reload({container:"#my-block"});
});
'); ?>
工作原理…
Pjax是任何代表片段的一个容器。它订阅片段中所有链接的点击事件,并替换整个页面,使用Ajax调用重新加载它。我们可以使用data-pjax
属性用于被包裹的表单,以及任何表单提交将会触发一个Ajax请求。
这个小组件将会加载和更新on-the-fly小组件内容,而不需要再加布局资源(JS,CSS)。
你可以配置小组件的$linkSelector
来指定什么链接将会触发Pjax,以及配置$formSelector
来指定什么样的表单提交将会触发Pjax。
你可以为容器中一个指定的链接禁用Pjax,方法是给这个链接添加一个data-pjax="0"
属性。
参考
- 欲了解更多关于这个扩展的用法,参考:
- 欲了解更多关于客户端选项和方法的信息,参考https://github.com/yiisoft/jquery-pjax#usage