#sorting #magento #grid
#сортировка #magento #сетка
Вопрос:
Я создал сетку в Magento, и есть столбец, который не поступает из базы данных, вместо этого я вычислил его значение из других столбцов с помощью средства визуализации. допустим, пользовательский столбец в сетке равен total = columnA из DB — ColumnB из DB, необходимо отсортировать сетку на основе пользовательского столбца. Я переопределил функцию setCollectionToOrder в своей сетке., отсортировал коллекцию, полученную из функции prepareCollection, и поместил отсортированную коллекцию в новый объект коллекции, но затем в моей сетке не отображается ни одной строки, хотя я могу повторить отсортированную коллекцию, и она работает нормально, но в сетке нет строк.
protected function _setCollectionOrder($column)
{
$collection = $this->getCollection();
if ($collection) {
switch ($column->getId()) {
case 'total':
$arr = array();
foreach($collection as $item) {
$colA= $item->getcolumnA();
$colB= $item->getcolumnB()
$total= $colA- $colB
$item->setTotal($total);
$arr[$i] = $item; $i ;
}
if($column->getDir()=='asc') {
$sorted = usort($arr, array('Grid_Class', '_cmpAscTotal'));
} else {
$sorted = usort($arr, array('Grid_Class', '_cmpDescTotal'));
}
$collection = $this->_tempCollection(); // A blank collection
for($i=0;$i<count($arr);$i ) {
$arr[$i]->setTotal(1);
$collection->addItem($arr[$i]);
}
$this->setCollection($collection);
break;
default:
parent::_setCollectionOrder($column);
break;
}
}
return $this;
}
Функция tempCollection просто дает мне пустой объект коллекции (то же, что дает функция prepare collection)
_cmpAscTotal — это функция обратного вызова, которая определяет мою пользовательскую сортировку.
protected function _prepareCollection()
{
$collection = Mage::getModel('module/model')->getCollection();
$collection->getSelect()->joinLeft(array('table1' => 'table1'),
'table1.sku = main_table.sku_id',
Array('columnA, columnB, (1) as total')
);
$this->setCollection($collection);
return parent::_prepareCollection();
}
Есть ли лучший способ получить отсортированную коллекцию в пользовательском столбце, если не то, что я делаю неправильно при изменении коллекции, чтобы сетка стала пустой
Ответ №1:
На самом деле, вам следует расширить класс collection и добавить свою пользовательскую сортировку в свой _afterLoad
метод сбора. Если по какой-то причине это невозможно — вы должны сделать это в своем сеточном _afterLoadCollection
методе. В любом случае, вы не можете / не должны / не делали этого в _setCollectionOrder
методе сбора. Потому что, если вы заглянете в Mage_Adminhtml_Block_Widget_Grid::_prepareCollection()
код — вы увидите, что _setCollectionOrder
это вызывается перед загрузкой коллекции.
Обновлено:
protected function _afterLoadCollection()
{
foreach ($this->getCollection() as $item) {
$item->setTotal($item->getcolumnA() - $item->getcolumnB());
}
usort($this->getCollection()->getIterator(), array('Grid_Class', '_cmpAscTotal'));
return $this;
}
Комментарии:
1. @ Zyava Я попытался распечатать свой пользовательский объект коллекции (который я устанавливаю в функции setCollectionOrder) в _afterLoadCollection, я могу получить его правильно отсортированным способом, но в сетке по-прежнему нет строк. Проблема здесь, я думаю, в том, что если я изменю тот же объект коллекции, который я получил из db, grid сможет это понять, но если я создам пустой объект коллекции frm db и добавлю элементы один за другим, grid не сможет этого понять. Любая помощь будет оценена!!
2. Хм, попробуйте отсортировать без временной коллекции.
3. Я использую Usort для сортировки, которая не вызывает функцию обратного вызова, если я ввожу collection, поэтому мне пришлось взять все элементы коллекции в массиве объектов, отсортировать их с помощью usort, а затем добавить все новые элементы в новый объект коллекции один за другим. Не могли бы вы подсказать мне какой-нибудь способ прямой сортировки коллекции?
4. Все еще не понимаю, почему вы не хотите создавать o = свой собственный класс коллекции и выполнять там всю обработку данных. Я обновил свой ответ фрагментом кода, попробуйте что-то подобное.
5. Как я могу получить общее количество отображаемых столбцов
Ответ №2:
Спасибо, Зява, я должен был сделать это так —
$arr = $this->getCollection()->getItems();
if($dir=='asc') {
$sorted = usort($arr, array('Grid_Class', '_cmpAscSuggestion'));
} else {
$sorted = usort($arr, array('Grid_Class', '_cmpDescSuggestion'));
}
$this->getCollection()->setItems($arrt); // created a set item function in collection class for this module.
Он сортирует элементы в коллекции.
Комментарии:
1. Привет, куда вы помещаете этот код? откуда
$dir
берется?