Yii2:对gridview

时间:2018-03-21 14:56:53

标签: gridview yii2

我有一个gridview,其中我显示了注册用户的纬度和范围之间的距离。经度(在他们的个人资料中设置)和gridview线的纬度&经度。我创建了一个帮助类,它给了我一个返回所述距离的功能 我的距离gridview是这样的:

        [
            'format'=>'raw',
            'attribute'=>'distance (km)',
            'value'=> function ($data) {
                $latFrom = Yii::$app->user->identity->profile->city->latitude;
                $longFrom = Yii::$app->user->identity->profile->city->longitude;
                $latTo = $data->createdBy->profile->city->latitude;
                $longTo = $data->createdBy->profile->city->longitude;

                return GeoHelper::distance($latFrom, $longFrom, $latTo, $longTo);
            },
        ],

我试图在gridview中添加距离排序,但似乎无法找到如何执行此操作。 我尝试将一个公共$ distance属性添加到搜索模型并将其设置为安全,然后添加

    $dataProvider->sort->attributes['distance'] = [
        'asc' => ['distance' => SORT_ASC],
        'desc' => ['distance' => SORT_DESC],
    ];

但没有运气

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

当然这不是问题,可以轻松解决。

要排序的值是在PHP中计算的,但DB对这些值没有任何线索。正如@Sergei Beregov所说,你可以使用ArrayDataProvider,是的,使用它可以实现的方式。但是,根据用户的数量,它可能非常昂贵(如果你有很多用户)

如果您的数据库支持Geo功能,我建议在DB本身中计算距离值。例如,在MySQL中,您可以使用ST_Distance()来计算两点之间的距离,并将其与Yii2中的ActiveRecord关系混合。我在我的博客Spatial relations in Yii2中使用地理功能编写了一个实验人员。对不起,这是俄语,但我希望它会有所帮助。

只要您可以计算数据库中的距离,就可以像'distance' => SORT_ASC

这样的常规方式轻松地对其进行排序。

答案 1 :(得分:1)

感谢Yerke的帮助我解决了! 在Post模型中,我创建了一个新的查找函数

public static function findWithDistance()
{
    $latitudeFrom = Yii::$app->user->identity->profile->city->latitude;
    $longFrom = Yii::$app->user->identity->profile->city->longitude;

    return parent::find()
        ->addSelect([
            "post.*",
            "round(6371 * acos( cos( radians(postcity.latitude) ) * cos( radians({$latitudeFrom}) ) * cos( radians({$longFrom}) - radians(postcity.longitude)) + sin(radians(postcity.latitude)) * sin( radians({$latitudeFrom})))) as distance",
        ])
        ->leftJoin('user', 'post.created_by = user.id')
        ->leftJoin('profile', 'user.id = profile.user_id')
        ->leftJoin('city postcity', 'profile.location = postcity.id');
}
如果用户已登录,我在PostSearch模型中调用

public function search($params)
{
    $query = (!Yii::$app->user->isGuest && Yii::$app->user->identity->profile->city!=null) ? Post::findWithDistance() : Post::find();
...

答案 2 :(得分:0)

在gridview列中,将属性定义为

'attribute'=>'distance (km)',

但在您的提供商中,您将其称为“距离”

$dataProvider->sort->attributes['distance']

尝试在gridview中设置列,如下所示:

'attribute'=>'distance',    

如果您需要在标题中显示“km”,请设置列的“标签”属性。