5

我需要在 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;
}

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

4

2 回答 2

1

更新:我是这个答案的作者,这个答案不准确。首选方式是使用数据库视图

添加两个公共属性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数组(所有属性obObject模型的列表)

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

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

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

欲了解更多信息,您可以访问Yii 的 Kartik 博客

于 2016-01-31T17:32:01.310 回答
0

虽然这是一个旧线程,但偶然发现并试图找到其他方法来实现对纯计算字段的排序无济于事......不幸的是,这篇文章也不是答案......只是我觉得有必要在此处发布它以提醒那些仍在寻找解决方案的人,以免在尝试给出的解决方案并且仍然失败时挠头。

据我测试,文档或引用链接中的给定示例仅在数据库架构中有列(无论是在主表还是相关表中)时才有效。如果您创建的虚拟属性/计算字段基于计算(例如表上 2 列的乘法),它将不起作用

例如:餐桌采购:| 购买ID | 产品编号 | 数量 | 餐桌产品:| 产品编号 | 单价 |

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

于 2020-07-30T02:11:07.580 回答