Yii2 GridView 分页只有 next 和 prev 链接,没有 TotalCount
Yii2 GridView pagination with only next and prev links and no TotalCount
有一个巨大的数据库 table 有数百万行,它需要在分页器中只有上一个和下一个链接的 GridView 中输出。
我不想在这样的 table 上使用 'select count(*)',所以没有 TotalCount。另外我想防止用户设置巨大的偏移量并降低 MySQL 性能。
谁能帮帮我?
当您创建数据提供者时,请确保将 totalCount 指定为一个数字,例如 0,这将阻止 Yii 运行 count(*) 查询。
然后您应该为 yii\widgets\Linkpager 创建一个替换 class,它只生成您想要显示的链接。
最后,将寻呼机附加到 GridView。
<?php GridView::widget([
'dataProvider'=>$dataProvider,
'pager' => [
'class' => 'path\to\my\custom\Pager\'
]
'columns' =>
....
]; ?>
我已经等了好几天以确保我没有遗漏一些明显的解决方案,但现在我需要自己对其进行硬编码。我发现最快的方法是扩展 DataProvider 并重写方法:prepareTotalCount()
、prepareModels()
:
namespace common;
use yii\data\ActiveDataProvider;
use yii\base\InvalidConfigException;
use yii\db\QueryInterface;
class BigActiveDataProvider extends ActiveDataProvider
{
protected function prepareTotalCount() {
return 0;
}
protected function prepareModels()
{
if (!$this->query instanceof QueryInterface) {
throw new InvalidConfigException('The "query" property must be an instance of a class that implements the QueryInterface e.g. yii\db\Query or its subclasses.');
}
$query = clone $this->query;
if (($pagination = $this->getPagination()) !== false) {
$pagination->validatePage = false;
$page = $pagination->getPage(true) + 1;
$offset = $page*$pagination->getPageSize();
$query->limit($pagination->getLimit() + 1)->offset($offset);
}
if (($sort = $this->getSort()) !== false) {
$query->addOrderBy($sort->getOrders());
}
$res = $query->all($this->db);
if (($pagination = $this->getPagination()) !== false) {
$pagination->totalCount = ($page)*$pagination->getPageSize();
if (count($res) > $pagination->getPageSize()) {
unset($res[count($res)-1]);
$pagination->totalCount++;
}
}
return $res;
}
}
我认为这不是最好的解决方案,但它按计划工作并且不限制 ActiveDataProvider
功能。它只确保不会执行 count(*) 查询并且不需要设置 totalCount
.
有一个巨大的数据库 table 有数百万行,它需要在分页器中只有上一个和下一个链接的 GridView 中输出。
我不想在这样的 table 上使用 'select count(*)',所以没有 TotalCount。另外我想防止用户设置巨大的偏移量并降低 MySQL 性能。
谁能帮帮我?
当您创建数据提供者时,请确保将 totalCount 指定为一个数字,例如 0,这将阻止 Yii 运行 count(*) 查询。
然后您应该为 yii\widgets\Linkpager 创建一个替换 class,它只生成您想要显示的链接。
最后,将寻呼机附加到 GridView。
<?php GridView::widget([
'dataProvider'=>$dataProvider,
'pager' => [
'class' => 'path\to\my\custom\Pager\'
]
'columns' =>
....
]; ?>
我已经等了好几天以确保我没有遗漏一些明显的解决方案,但现在我需要自己对其进行硬编码。我发现最快的方法是扩展 DataProvider 并重写方法:prepareTotalCount()
、prepareModels()
:
namespace common;
use yii\data\ActiveDataProvider;
use yii\base\InvalidConfigException;
use yii\db\QueryInterface;
class BigActiveDataProvider extends ActiveDataProvider
{
protected function prepareTotalCount() {
return 0;
}
protected function prepareModels()
{
if (!$this->query instanceof QueryInterface) {
throw new InvalidConfigException('The "query" property must be an instance of a class that implements the QueryInterface e.g. yii\db\Query or its subclasses.');
}
$query = clone $this->query;
if (($pagination = $this->getPagination()) !== false) {
$pagination->validatePage = false;
$page = $pagination->getPage(true) + 1;
$offset = $page*$pagination->getPageSize();
$query->limit($pagination->getLimit() + 1)->offset($offset);
}
if (($sort = $this->getSort()) !== false) {
$query->addOrderBy($sort->getOrders());
}
$res = $query->all($this->db);
if (($pagination = $this->getPagination()) !== false) {
$pagination->totalCount = ($page)*$pagination->getPageSize();
if (count($res) > $pagination->getPageSize()) {
unset($res[count($res)-1]);
$pagination->totalCount++;
}
}
return $res;
}
}
我认为这不是最好的解决方案,但它按计划工作并且不限制 ActiveDataProvider
功能。它只确保不会执行 count(*) 查询并且不需要设置 totalCount
.