Pjax 高级用法

Yii Framework 2.0 内置了对 Pjax 的支持, Pjax是一个减少页面加载时间的 JavaScript 库。它通过仅更新通过 Ajax 更改的页面部分来实现这一点,如果你的页面上有许多其他资源,这可以节省大量成本。我们的一些项目使用此功能,我们希望分享一些经验教训。

问题 :第 1 页是一个包含很少元素的简单静态页面。第 2 页包含 ActiveForm 以及其他小部件。需要加载 ActiveForm JavaScript 资源才能运行内联 JavaScript,但由于第 1 页不包含这些资产,因此在尝试执行 activeform 行时会遇到 JavaScript 错误:‘Uncaught TypeError:undefined 不是功能’。

解决方案 :将 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。调查 div ID,我们看到 ActiveForm 期望 ID 为#w1,但是 NavBar 已经在 Page 1 上分配了该 ID,因为那是该页面上遇到的第一个小部件。

解决方案 :不要依赖 Yii 为你自动生成小部件 ID。相反,在创建窗口小部件时始终传入 ID 以保持对这些 ID 的控制。

问题 :Pjax 请求在请求启动后的 1000 毫秒内被取消。

解决方案 :增加 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 的经历是什么?如果你发现任何陷阱或有比我们更好的解决方案,请在下方评论!