列的Yii2 DataPorivider $ totalSum

时间:2016-07-19 11:50:06

标签: gridview yii2

我有Order和OrderSearch模型。

在GridView的顺序列表(actionIndex)中有一个过滤和排序。 Order中的列是order_total(按顺序排列所有产品的总和)。

我需要在GridView中实现所有order_total的SUM。 如果我通过使用array_map计算ActiveDataProvider-> getModels()来手动执行此操作,则我需要花费3秒来完成3000个订单(localhost)。我不想错过那么多时间。

我认为有两种方法可以加快速度:

  1. 为每个过滤器创建缓存并按生命周期更新(可怕)
  2. 最有趣的是,我可以在OrderSearch-> search()方法中将其作为$ query方法。但我不明白如何在控制器中传递它。
  3. 第二种方式的代码示例:

    class OrderSearch extends Order
    {
    
        public $totalSum; 
    
        public function search($params)
        {
            $query = Order::find();
    
            $dataProvider = new ActiveDataProvider([
                'query' => $query,
            ]);
    
            $this->load($params);
    
            $this->totalSum = $query->sum('order_total'); // this works very fast
    
            return $dataProvider;
        }
    
    }
    

    之后我试图在Controller中获取此属性:

    public function actionIndex()
    {
        $searchModel = new OrderSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);
    
        $dataProvider->pagination->pageSize = 100;
    
        // code below works too slow and depends on pagination page size
        // $orders = $dataProvider->getModels();
        // $totalSum = 1.0;
        // array_map(function($item) use (&$totalSum) {
        //     $totalSum += (float)$item->attributes['order_total'];
        // }, $dataProvider->getModels());
    
        // here I get an error
        // Unknown Property – yii\base\UnknownPropertyException
        // Getting unknown property: yii\data\ActiveDataProvider::totalSum
        $totalSum = $dataProvider->totalSum;
    
        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,
            'totalSum' => $totalSum,
        ]);
    }
    

    如何为DataProvider设置自定义属性?

2 个答案:

答案 0 :(得分:2)

您写道:

$dataProvider = $searchModel->search(Yii::$app->request->queryParams);

因此,$dataProvider将是该方法的返回。而且,正如你在这里看到的那样:

public function search($params)
{
    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    // code

    return $dataProvider;
}

方法search正在返回ActiveDataProvider。在使用该方法之后,您应该调用原始类的属性:

$searchModel = new OrderSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams); // run search, so now we have a totalSum.
$totalSum = $searchModel->totalSum;

答案 1 :(得分:0)

获取$totalSum并添加字段。

变化

$query = Order::find();

$query = Order::find()->select(['*', 'totalSum' => new yii\db\Expression($totalSum)]);

如果您使用字符串,请注意转义!

您还可以考虑使用子查询,例如http://www.yiiframework.com/doc-2.0/guide-db-query-builder.html

e.g。

$subQuery = Order::find()->sum('order_total');
$query = Order::find()->select(['*', 'totalSum' => $subQuery]);