【问题标题】:yii2 Ignore pagination for calculationyii2 忽略分页计算
【发布时间】:2018-04-13 21:36:17
【问题描述】:

我有一个 GridView 表,我想在其中计算余额,因为在数据库中只有借方和贷方。 我在模型中添加了一个新的对象变量balance 和一个类变量tempBalance,它保持最后的平衡。

在 SearchModel 中,我有以下几行来计算余额

private function calculateBalance($dataProvider) {
    foreach ($dataProvider->models as $model) {
        $model->balance = parent::$tempBalance + $model->debit - $model->credit;
            parent::$tempBalance = $model->balance;
        }
}

这很好用,但是当我在 GridView 中有超过 20 个结果时,它会自动生成每 20 条记录的页面(我想保留这个分页)。问题是,在每一页上,saldo 都以 0 开头,但我显然仍然希望保留上一页最后一个条目的saldo。

我试图关闭计算的分页,然后再次打开它,但这就是我挣扎的地方。

我尝试在calculateBalance() 方法中的foreach-loop 之前关闭分页:

$pagination = $dataProvider->getPagination();
$dataProvider->setPagination(false);

然后通过以下代码在循环后再次打开它:

$dataProvider->setPagination($pagination);

但这并没有再次打开分页。分页仍然关闭。

有没有办法在我的计算中忽略分页,或者它是关闭并重新打开分页的正确方法?

关闭后如何打开分页?

【问题讨论】:

    标签: php gridview yii2


    【解决方案1】:

    $dataProvider->models 被缓存,如果您要更改分页设置,您必须调用$dataProvider->prepare(true) 来强制数据提供者从数据库中重新获取数据。

    类似:

    // setup $dataProvider
    // render GridView
    
    $dataProvider->setPagination(false);
    $dataProvider->prepare(true);
    $this->calculateBalance($dataProvider);
    

    但是在模型上计算余额是一个非常糟糕的主意——如果有人有数百万条记录,它会非常慢,最后你会出现内存不足的错误。您应该通过 SQL 查询计算余额 - 它会更快,并且不会因大量数据而崩溃。

    $balanceQuery = clone $dataProvider->query;
    $balanceQuery->select([
        'debit' => new Expression('SUM(debit)'),
        'credit' => new Expression('SUM(credit)'),
    ]);
    $balanceData = $balanceQuery->asArray()->one();
    $balance = $initialBalance + $balanceData['debit'] - $balanceData['credit'];
    

    请注意,过滤网格数据会改变平衡(因为$dataProvider->query 会忽略一些数据)。如果这不是故意的,您可能应该在应用过滤之前克隆 $query 或使用新查询,例如 $balanceQuery = MyModel::find()->onlyForUser($userId);

    【讨论】:

    • 谢谢!再次查看 SQL 查询并使用 SQL 帮助我;)
    猜你喜欢
    • 2013-04-20
    • 2013-09-13
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多