在Yii2中排序计算字段(网格视图)

时间:2016-01-30 13:46:15

标签: php sorting gridview yii2 yii2-model

我需要在GridView中对某些字段(asc,desc)进行排序,但会计算相同的字段。看下面的代码: 的 SearchModel:

class ObjectSearch extends Object {
use SearchModelTrait;

public function rules()
{
    return [
        ['id', 'integer', 'min' => 1],
    ];
}

public function search($params)
{
    $this->company_id = \Yii::$app->user->identity->companyId;
    $query = Object::find()->where(['company_id' => $this->company_id]);
    $dataProvider = new ActiveDataProvider([
        'query' => $query,
        'pagination' => false,
    ]);
    $dataProvider->setSort([
        'attributes' => [
            'id',
            'name',
            'lastReportResult' => [
                'asc' => ['lastReportResult' =>SORT_ASC ],
                'desc' => ['lastReportResult' => SORT_DESC],
                'default' => SORT_ASC
            ],
            'reportPercentDiff'
        ]
    ]);

    if (!($this->load($params,'ObjectSearch') && $this->validate())) {
        return $dataProvider;
    }

    $this->addCondition($query, 'id');

    return $dataProvider;
}

对象模型中的方法:

public function getLastReportResult()
{
    $lastReport = $this->getLastReport();
    $message = 0;

    if (!empty($lastReport)) {
        $statistic = new ReportStatistic($lastReport);
        $message = $statistic->getPercent();
    }

    return $message;
}

/**
 * @return int
 */
public function getReportPercentDiff()
{
    $lastReport = $this->getLastReport();
    $message = 0;

    if (!empty($lastReport)) {
        $statistic = $lastReport->getReportDiff();

        if (!empty($statistic['diff'])) {
            $message = $statistic['diff']['right_answers_percent_diff'];
        } elseif (!empty($statistic['message'])) {
            $message = $statistic['message'];
        }
    }
    return $message;
}

所以,通过这种方法,我正在计算两个字段的值,这是需要的排序。这种方式不起作用,我有一个数据库异常,因为对象表没有这个字段。 exception 如何对这些字段进行排序?

2 个答案:

答案 0 :(得分:2)

将两个公共属性添加到ObjectSearch.php并将其标记为安全

class ObjectSearch extends Object {
    use SearchModelTrait;
    public $lastReportResult, $reportPercentDiff;
    public function rules()
    {
        return [
            ['id', 'integer', 'min' => 1],
            [['lastReportResult', 'reportPercentDiff'], 'safe']
        ];
    }

    public function search($params)
    {
        $this->company_id = \Yii::$app->user->identity->companyId;
        $query = Object::find()->where(['company_id' => $this->company_id]);
        $dataProvider = new ActiveDataProvider([
            'query' => $query,
            'pagination' => false,
        ]);
        $dataProvider->setSort([
            'attributes' => [
                'id',
                'name',
                'lastReportResult' => [
                    'asc' => ['lastReportResult' =>SORT_ASC ],
                    'desc' => ['lastReportResult' => SORT_DESC],
                    'default' => SORT_ASC
                ],
                'reportPercentDiff' => [
                    'asc' => ['reportPercentDiff' =>SORT_ASC ],
                    'desc' => ['reportPercentDiff' => SORT_DESC],
                    'default' => SORT_ASC
                ],                
            ]
        ]);

        if (!($this->load($params,'ObjectSearch') && $this->validate())) {
            return $dataProvider;
        }

        $this->addCondition($query, 'id');

        return $dataProvider;
}

然后在index.php(您正在查看网格视图的文件中)在所有属性的数组中添加lastReportResultreportPercentDiff(所有属性列表ob Object模型)

...
<?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        ['class' => 'yii\grid\SerialColumn'],


        // your other attribute here
        'lastReportResult',
        'reportPercentDiff',

        ['class' => 'yii\grid\ActionColumn'],
    ],
]); ?>
...

有关详细信息,请访问Kartik's blog at Yii

答案 1 :(得分:0)

尽管这是一个旧线程,但偶然发现了这个问题,并试图找到其他方法来对纯计算字段进行排序无济于事……不幸的是,该帖子也没有答案...我只是觉得有必要将其张贴在此处,以提醒仍在寻找解决方案的人员,以免在尝试给出的解决方案时仍然scratch之以鼻。

据我所测试,文档或引用链接中给出的示例仅在数据库模式中有一个列(无论是在主表还是相关表中)时才有效。如果您创建的虚拟属性/计算字段基于计算(例如,表中2列的乘积),它将无法正常工作

例如: 餐桌购买: Purchase_id | product_id |数量 餐桌产品: product_id | unit_price |

然后,如果我们对模型“ purchase”使用虚拟属性“ purchase_total”,即数量和unit_price的乘积(来自product_id上的purchase_product的联接表),最终您将遇到一个错误,提示“ purchase_total”当您尝试使用到目前为止讨论的方法对它们进行排序时,找不到列。