我有Order和OrderSearch模型。
在GridView的顺序列表(actionIndex)中有一个过滤和排序。 Order中的列是order_total(按顺序排列所有产品的总和)。
我需要在GridView中实现所有order_total的SUM。 如果我通过使用array_map计算ActiveDataProvider-> getModels()来手动执行此操作,则我需要花费3秒来完成3000个订单(localhost)。我不想错过那么多时间。
我认为有两种方法可以加快速度:
第二种方式的代码示例:
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设置自定义属性?
答案 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]);