今年の梅雨は雨が少ない印象を受けます。窓を開けて換気していてもそれ程湿度を感じません。昨日はよく寝れて、体調は良い感じです。
さて、久々にYii2の話題です。大分Yii2も使い慣れてきて、ノウハウが溜まってきました。今回はPjaxの使い方のメモです。
Pjaxとは
pushstate + Ajax = Pjaxです。 実態はJavaScriptのライブラリで、Ajaxは非同期に通信を行うもの、pushstateはブラウザの履歴を更新するものです。
よく使われる例だと、「次のページ」「前のページ」のリンクがあり、複数ページを表示するウェブページで、「次のページ」をクリックした場合に、ページの中身だけを次のページの内容に更新、ブラウザの「戻る」をすると前のページに戻るようにするといったものです。
使い方
Yii2でPjaxを使うのはとても簡単です。
Pjax::begin()とPjax::end()で囲う
囲われた部分の、ボタンやリンクなどが自動的にPjaxに置き換えられ、更新がAjaxで行われ、ブラウザの履歴に登録されるようになります。
<?php Pjax::begin(); ?> ... <?php Pjax::end(); ?>
formに'data-pjax' => '1' を追加する
submitした時にPjaxで更新して欲しいフォーム(検索フォームなど)は、'data-pjax' = '1' を追加します。
<?php $form = ActiveForm::begin(['options' => ['data-pjax' => '1']]); ?>
注意点
今の所気づいた注意点を挙げておきます。
htmlに記述するonchangeはPjaxで制御されない
以下のようにhtmlにonchangeでsubmitするように記載すると、Pjaxでの読込みが行われません。試していませんが、onclickも同様と思います。
<input onchange="submit(this.form)">
この場合、jqueryなどでsubmitすればPjaxでの読込みになります。
$(document).on('change', '#input', function(){ $('#form').submit(); })
jqueryで、onを使う時にはoffもペアで使う
これはPjaxというより、jqueryでの注意事項ですが、Pjaxだと起こりやすい問題です。on('change')だけを使うと、複数回変更した場合に、changeイベントが何回も実行されてしまいます。それを防ぐために、off('change')をon('change')の前に実行するようにします。
$(document).off('change', '#input'); $(document).on('change', '#input', function(){ $('#form').submit(); })
詳しくは以下を参照してください。
Pjaxを実行されたくない操作は、'data-pjax'='0'を指定する
別のページに遷移するボタンやリンク(target=_blankも)などは、Pjaxでの読み込みが行われないようにする必要があります。 その場合には、'data-pjax'='0'をhtmlに指定します。
echo Html::a('新規登録', 'create', [ 'class' => 'btn btn-primary', 'data-pjax' => '0' ]);
ちなみに、yii\grid\ActionColumnのデフォルトのボタンは、data-pjax'='0'が指定されています。
formのsubmitはformに指定したdata-pjax指定に従う
つまり、複数submitボタンがある場合、片方はPjaxあり、片方はPjaxなしという使い方はできません。
これを実現したければ、片方は普通のボタン(data-pjaxを指定)にして、jqueryなどで独自にsubmitを定義してやる必要があります。
modalではPjaxは使用しない
Modal上でPjaxを使うと更新をかけた際にmodalが閉じてしまう現象が起きました。 ググって調べて、タイムアウトを長くしてみたり、pushstateを無効にしてみたりと色々試したのですが、防ぐことができませんでした。
仕方なくmodalではPjaxをあきらめ、ajaxで更新するようにしています。ただ、私のやり方が悪いだけで、できるのかもしれません。
こんなところです。