Сортировка сетки Magento по отображаемому столбцу

#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 берется?