【问题标题】:Yii Dataprovider date sortingYii DataProvider 日期排序
【发布时间】:2014-10-13 01:58:17
【问题描述】:

我有 ArrayDataProvider,其字段类型为 DateTime - 生日。 我将该数据提供程序用于视图部分中的网格视图。

由于生日包含出生年份,因此排序未按预期工作。 有没有办法告诉排序机制不计算年份,只按月和日排序?也许是自定义排序功能?

编辑: 类似 C++ 中的 sort 的东西,您可以在其中传递比较函数。

编辑当前解决方案说明: 我目前的解决方案是将出生年份作为一个单独的字段包含在数组中,并将出生日期的年份设置为当前年份。现在日期来自同一年并且排序工作。但是出生年份的单独字段感觉不对。我希望我能从一个日期对象中获取所有必要的数据。

这个独立的领域磨砺了我的齿轮。这并不完美。

编辑: 哦,还有它的 Yii2

更新 还有一个 PHP 数组排序函数接受比较回调 - 例如 uasort 可以用于像我这样的关联数组:

uasort($persons, function($a, $b){
    return strcasecmp( $b['date']->format('m-d'), $a['date']->format('m-d') );
});

现在我需要找到将它实现到 ArrayDataProvider 中的方法。这里有什么想法吗?

【问题讨论】:

  • 请发布您的代码
  • 我认为这里没有使用任何代码。您可以在 ArrayDataProvider 或任何数据提供者上设置自定义排序吗?

标签: php sorting gridview yii2 dataprovider


【解决方案1】:

如果你有一个数组数据提供者,你当然不能使用数据库的排序。

使用 Yii 的解决方案

要允许按某些表达式排序,您必须事先计算值并配置属性的排序以使用计算值而不是原始值:

// assuming $data contains your data and 'birthdate' is the value you want to use for sorting

foreach($data as $key => $value) {
    $data[$key]['sort_birthdate'] = date('m-d', strtotime($value['birthdate']));
}
$dataProvider = new \yii\data\ArrayDataProvider([
    'allModels' => $data,
    'sort' => [
        'attributes' => [
            'birthdate' => [
                'asc' => [
                    'sort_birthdate' => SORT_ASC, 
                ],
                'desc' => [
                    'sort_birthdate' => SORT_DESC, 
                ],
                'label' => 'Date',
                'default' => SORT_ASC
            ],
            // list all other attributes here
        ],
    ]
]);

扩展 Yii 的解决方案

如果你想要一个自定义的比较函数,你必须扩展 Yii 类来支持它。 你可以创建一个自定义的 ArrayDataProvider 类,它继承自 Yii 自带的类并覆盖 sortModels()-方法。

【讨论】:

  • 嗯,这几乎就是 ArrayDataProvider 对象获取数据之前所做的工作。我将对问题添加澄清评论。谢谢。
  • Yii 不支持这个。更新了我的答案以显示如何扩展 Yii 以添加此内容。
  • 我会尽快调查。看起来很有希望,但最终可能会比我的简单应用程序所需的开销更多。会好好学习的。非常感谢您的宝贵时间。
  • 顺便说一句,当遇到同样的问题时,任何人都知道您可能走错了路。在我看来,Yii 确实可以通过设计解决很多问题,对我来说,所有问题都是通过发现“虚拟属性”(初学者错误)来解决的。现在一切都很完美:)
  • 好吧,您根本没有提到您正在使用 AR。 :)
【解决方案2】:

你应该尝试类似的东西

use yii\db\Expression;
$dataProvider->setSort([
            'attributes' => [
................................
                'birthday' => [
                    'asc' => [
                        new Expression('DATE_FORMAT(birthday, "%m%d")') => SORT_ASC, 
                    ],
                    'desc' => [
                        new Expression('DATE_FORMAT(birthday, "%m%d")') => SORT_DESC, 
                    ],
                    'label' => 'Birthday',
                    'default' => SORT_ASC
                ],
................................
            ]
        ]);

我没试过。

确实有效的是做这样的事情

$query->select([
                    new Expression('DATE_FORMAT(birthday, "%m%d") as show_date'), 
      .................................
                ]);

然后

    /**
     * Setup your sorting attributes
     * Note: This is setup before the $this->load($params) 
     * statement below
     */
     $dataProvider->setSort([
        'attributes' => [
            'id',
            'show_date' => [
                'asc' => [
                    'sort_date' => SORT_ASC, 
                ],
                'desc' => [
                    'sort_date' => SORT_DESC, 
                ],
                'label' => 'Date',
                'default' => SORT_ASC
            ],
            'price',
            'gst',
            'cost',
            'quantity',
            'profit',
        ]
    ]);

【讨论】:

  • 我想如果数据来自数据库,它会起作用。我的数据来自数据库,但在我展示给人类消费之前,必须做一些准备工作。所以我很遗憾不能使用 SQL 对日期进行排序。
  • yiiframework.com/doc-2.0/yii-data-arraydataprovider.html 获取数组,根据需要在其中创建一个包含数据的字段(在本例中为月-日),将其用作排序属性。在 GridView 中使用 ArrayDataProvider。
  • 是的,这是我的问题 - 排序工作所需的额外字段。但是我可以通过回调或 smth 来挂钩该字段的实际排序吗? ?比较函数回调。
  • 为什么会有问题?它是数组中的一个字段。遍历数组,向其中添加一个新字段。使用数组数据提供程序中的字段。你说你已经“准备”了它......也添加到你的“准备”中。
  • 我知道了,您已经拥有了这样的解决方案,但您不喜欢该解决方案。抱歉,我没有其他想法,但我知道你想做什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多