2014-10-13 3 views
2

У меня есть ArrayDataProvider с полем типа DateTime - дата рождения. Я использую этот dataprovider для gridview в виде секции.Yii Датапровердер Дата сортировки

С момента рождения, включая рождение, сортировка не работает должным образом. Есть ли способ каким-то образом объяснить механизм сортировки не для учета лет и только сортировать по месяцам и дням? Возможно пользовательская функция сортировки?

Редактировать: Нечто вроде sort на C++, где вы можете передать функцию сравнения.

Edited описание текущего решения: Моего решения в настоящее время включает в год рождения в качестве отдельного поля в массиве и года BirthDate в установлены на текущий год. Теперь даты относятся к тому же году, и сортировка работает. Но отдельное поле для года рождения не кажется правильным. Я хотел бы получить все необходимые данные из одного объекта даты.

Это отдельное поле измельчает мои шестерни. Это не идеально.

Edit: О, и его Yii2

Update Есть также PHP массив сортировки, принимающих параметр сравнения обратного вызова - например uasort, которые могут быть использованы на ассоциативные массивы, как у меня:

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

Теперь мне нужно найти способ реализовать его в ArrayDataProvider. Есть идеи?

+0

доброжелательно опубликовать свой код – Athipatla

+0

Я не думаю, что здесь есть код.Можете ли вы настроить пользовательскую сортировку на ArrayDataProvider или на любом из поставщиков данных? – Klamberext

ответ

2

Если у вас есть массив DataProvider вы не можете использовать сортировку базы данных, конечно.

Решение с использованием 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()-метод.

+0

Ну, это в значительной степени то, что делается до того, как объект ArrayDataProvider получит данные. Я добавлю поясняющий комментарий к вопросу. Благодарю. – Klamberext

+0

Это не поддерживается Yii. Обновлен мой ответ, чтобы показать, как расширить Yii, чтобы добавить это. – cebe

+0

Я скоро загляну в него. Кажется многообещающим, но может оказаться более накладным, чем это необходимо для моего простого приложения. Будет хорошим обучением. Большое спасибо за ваше время. – Klamberext

1

Вы должны попробовать что-то вроде

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', 
     ] 
    ]); 
+0

Я бы хотел, чтобы он работал, если данные были из базы данных. Мои данные взяты из базы данных, но прежде чем я смогу отобразить ее для человеческого потребления, необходимо сделать подготовительные работы. Поэтому я, к сожалению, не могу использовать SQL для сортировки дат. – Klamberext

+0

http://www.yiiframework.com/doc-2.0/yii-data-arraydataprovider.html Получите массив, создайте в нем поле с необходимыми данными (в этом случае месяц-день) используйте его как атрибут сортировки. Используйте ArrayDataProvider в своем GridView. –

+0

Да, это моя проблема - дополнительное поле, необходимое для работы сортировки. Но могу ли я подключиться к фактической сортировке этого поля с помощью обратного вызова или smth. ? Сравнить функцию обратного вызова. – Klamberext

Смежные вопросы