首页 > 解决方案 > 如何在 Yii2 中保存 GridView 过滤器以进行分页

问题描述

有一个页面显示了 GridView:

// OrderController

public function actionIndex()
{
    $dataProvider = new ActiveDataProvider([
        'query' => Model::find(),
        'sort' => false,
        'pagination' => [
            'pageSize' => 15,
            'route' => '/order'
        ],
    ]);

    return $this->render('index', [
        'dataProvider' => $dataProvider,
    ]);
}

页面上有用于过滤表中信息的按钮。当您单击它们时,将向loadData方法发送一个带有必要参数的 Ajax 请求。然后结果显示在页面上。

// OrderController

public function actionLoadData()
{
    Yii::$app->response->format = Response::FORMAT_JSON;

    if (Yii::$app->request->isAjax)
    {
        ...

        $dataProvider = new ActiveDataProvider([
            'query' => Model::find()->accounts($selectedAccountsIds)
            'sort' => false,
            'pagination' => [
                'pageSize' => 15,
                'route' => '/order'
            ],
        ]);
        
        return [
            'success' => true,
            'render' => $this->renderPartial('parts/_table', [
                'dataProvider' => $dataProvider
            ])
        ];
    }

    ...
}

GridView 包装在 Pjax 中,因此分页无需重新加载即可工作。

<?php Pjax::begin(['timeout' => 5000]) ?>
    <div class="table-responsive">
        <?= GridView::widget([
            'dataProvider' => $dataProvider,
           ...
        ]); ?>
    </div>
<?php Pjax::end() ?>

而现在,事实上,问题本身。描述它的最简单方法是步骤的形式:

  1. 加载的页面,数据取自actionIndex()
  2. 用户单击按钮,向actionLoadData()发送 Ajax 请求
  3. 渲染新的 GridView
  4. 当您单击分页时,数据从actionIndex()加载,没有过滤器

这是合乎逻辑的,因为通过逐页导航,请求将转到actionIndex()。问题是,我如何告诉actionIndex()需要在考虑过滤器的情况下检索数据?

我脑子里只有两个选择。第一种是在成功的 Ajax 请求后使用 JavaScript 向 URL 参数添加过滤信息,例如...&daterange=week,并在actionIndex()中获取它们并进行必要的操作。第二个是相同的,但带有cookie。

// actionIndex() - Example with GET params
if (Yii::$app->request->isPjax)
{
    $dateRange = Yii::$app->request->get('dateRange');
    ...
}

我创建了一个 JavaScript 函数,它将必要的参数添加到 url。在 ajax 请求之后,我的 URL 如下所示:

http://site.loc/order?selected_ids=%5B1%2C4%5D

但是,如果您查看为分页而形成的链接,它们看起来像这样:

http://site.loc/order?page=2

我需要它们看起来像这样:

http://site.loc/order?selected_ids=%5B1%2C4%5D&page=2

在actionIndex( )actionLoadData()中,我将路由参数更改为:

    $dataProvider = new ActiveDataProvider([
        'query' => Model::find(),
        'sort' => false,
        'pagination' => [
            'pageSize' => 15,
            'route' => '/order' . Yii::$app->request->queryString
        ],
    ]);

但这只会进一步破坏 URL……cookie 只剩下一个选项,但对我来说似乎也值得怀疑。

如果有人遇到过类似的问题,请分享您的经验。谢谢!

标签: phpgridviewpaginationyii2

解决方案


我通过使用 cookie 解决了这个问题。最初加载页面时,会检查是否存在 cookie,如果有,则使用必要的过滤器获取数据,如果没有,则设置默认过滤器。作为一个不错的奖励,重新加载页面后会保存过滤器设置:)


推荐阅读