yii2
Pjax
サーチ…
ステップ1構造を追加する
ビュー\ site \ form-submission.php
<?php Pjax::begin(['id'=>'id-pjax']); ?>
<?= Html::beginForm(['site/form-submission'], 'post', ['data-pjax' => '', 'class' => 'form-inline']); ?>
<?= Html::input('text', 'string', Yii::$app->request->post('string'), ['class' => 'form-control']) ?>
<?= Html::submitButton('Hash String', ['class' => 'btn btn-lg btn-primary', 'name' => 'hash-button']) ?>
<?= Html::endForm() ?>
<h3><?= $stringHash ?></h3>
<?php Pjax::end(); ?>
ステップ2サーバーサイドコード
public function actionFormSubmission()
{
$security = new Security();
$string = Yii::$app->request->post('string');
$stringHash = '';
if (!is_null($string)) {
$stringHash = $security->generatePasswordHash($string);
}
return $this->render('form-submission', [
'stringHash' => $stringHash,
]);
}
pjaxの使い方
ビューの先頭にこの行を追加します。
<?php
use yii\widgets\Pjax;
?>
部分的な更新が必要なコンテンツの周りに次の2行を追加します。
<?php Pjax::begin(['id'=>'id-pjax']); ?>
Content that needs to be updated
<?php Pjax::end(); ?>
pjaxをリロードする
$.pjax.reload({container: '#id-pjax'});
pjaxでタイムアウト引数を使用する
<?php Pjax::begin(['id'=>'id-pjax', 'timeout' => false]); ?>
timeout引数の整数値を指定できます。これは、待機するミリ秒数(デフォルト値は1000)です。サーバーの実行時間がこのタイムアウト値より大きい場合は、フルページロードがトリガーされます。
デフォルトでは、pjaxはGETメソッドを使用してフォームを送信します。次の例のように、フォーム送信メソッドをPOSTに変更できます
<?php Pjax::begin(['id'=>'id-pjax', 'timeout' => false, 'clientOptions' => ['method' => 'POST']]); ?>
Pjaxの高度な使い方
Yii Framework 2.0には、ページ読み込み時間を短縮するJavaScriptライブラリPjaxが組み込まれています。これは、Ajaxによって変更されたページの一部を更新するだけで済みます。これにより、ページに他の多くのアセットがある場合に大幅な節約につながります。いくつかのプロジェクトではこの機能を使用しており、学習した教訓を共有したいと考えていました。
問題 :ページ1は、少数の要素しか含まない単純な静的ページです。ページ2には、ActiveFormと他のウィジェットが含まれています。インラインJavaScriptを実行するためには、ActiveForm JavaScriptリソースをロードする必要がありますが、Page 1にはこれらのアセットは含まれていないため、アクティブフォーム行を実行しようとするとJavaScriptエラーが発生しました: 'Uncaught TypeError:undefined is a関数'。
解決策 :すべてのページにロードされる共有アセットバンドルにActiveFormアセットを含め、エントリページで正しいスクリプトを使用できるようにします。
class AppAsset extends AssetBundle
{
...
public $depends = [
'yii\widgets\ActiveFormAsset',
'yii\validators\ValidationAsset',
];
...
}
問題 :上記の例では、ページ1にいくつかのウィジェット(NavBarなど)が含まれています。ページ2には、同じウィジェットと、さらにいくつか(ActiveFormなど)が含まれています。 Pjaxを介してページをロードするとき、カスタムインラインJavaScriptが実行されていましたが、ActiveFormウィジェットによって配置されたインラインスクリプトは、検証コードが機能していないため動作していませんでした。デバッグでは、ActiveForm init関数が実行されていましたが、 'this'変数はActiveFormに対応していないようです。これは実際にNavBar divに対応しています。部門IDを調べると、ActiveFormはIDが#w1であると予想していましたが、NavBarはそのページで最初に見つかったウィジェットであるため、そのIDが割り当てられていました。
解決策 :ウィジェットIDを自動生成するためにYiiに依存しないでください。代わりに、ウィジェットを作成するときにIDを渡して、それらのIDの制御を維持してください。
問題 :要求が開始されてからPjax要求が正確に1,000ミリ秒キャンセルされました。
解決策 :Pjaxのタイムアウト設定を増やしてください。デフォルトでは1秒に設定されています。これは本番サイトでは許容されるはずです。しかし、開発中、xdebugを使用している間は、ページの読み込み時間がこの制限を超えています。
問題 :WebアプリケーションがPost-Redirect-Get(PRG)パターンを実装しています。 Pjaxはリダイレクトだけでなくページ全体をリロードします。
解決策 :これはPjaxの意図された動作です。リダイレクトはPjaxを使用しているときにその目的を果たさないため、要求がPjaxであるかどうかを判断し、そうであれば、リダイレクトする代わりにコンテンツをレンダリングします。例は次のようになります。
$endURL = "main/endpoint";
if (Yii::$app->request->isPjax) {
return $this->run($endURL);
} else {
return $this->redirect([$endURL]);
}
PjaxとYiiの経験は何ですか?もしあなたが何か問題を発見したか、私たちよりも優れた解決策を持っていれば、以下のコメントをください!