Изменение порядка отображения

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
zbd
Сообщения: 20
Зарегистрирован: 2011.03.08, 02:30

Изменение порядка отображения

Сообщение zbd »

Приветствую!

Каким образом в Yii реализован механизм изменения последовательности записей при отображении. Например, древо каталога, необходимо один из элементов поднять/опустить вверх относительно родителя.

Аватара пользователя
mitaichik
Сообщения: 512
Зарегистрирован: 2010.09.24, 21:18
Откуда: Россия, Санкт-Петербург

Re: Изменение порядка отображения

Сообщение mitaichik »

Чисто Yii такого не делает.
Это надо реализовывать самостоятельно (я про дерево). А для сортировки - делай поле position и присваивай ему нужное значение, в defaultScopes модели пиши order => position
Есть расширение nestedSets - возможно там есть готовое, я им не пользовался.

zbd
Сообщения: 20
Зарегистрирован: 2011.03.08, 02:30

Re: Изменение порядка отображения

Сообщение zbd »

mitaichik писал(а):А для сортировки - делай поле position и присваивай ему нужное значение, в defaultScopes модели пиши order => position
  • В модели мы переопределяем метод defaultScopes(). А что дальше, каким образом мне указать поле (parent) в рамках которого происходит сортировка?
  • Как мне указать, что бы при создании поле увеличивалось на единицу, т.е. становился последним в последовательности?
  • Как реализована валидация порядка сортировки, что бы не получилось, что то типа 1, 2, 5, 6?
  • Какие методы реализут поднять и опустить позицию?
Всё это можно реализовать и самому, но если весь этот набор присутствует, изобретать велик не хочется :D .

ikarushka
Сообщения: 39
Зарегистрирован: 2010.11.23, 15:49

Re: Изменение порядка отображения

Сообщение ikarushka »

Присоеденяюсь к вопросам zbn.
Раз никто не ответил - по-видимому, придется изобретать велик?

Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Изменение порядка отображения

Сообщение slavcodev »

Я например не очень понял вопросов и не отвечал, попробую предположить что имелось виду
1)

Код: Выделить всё

public function defaultScope()
{
  return array(
    'order'=>'parent DESC',
  );
} 
2) При вставке записи, я не ищу какое там последнее число (лишний запрос), я ставлю COUNT, можно использовать MAX, т.е все средствами Mysql
3) А для чего? Чем плоха такая последовательность?
4) Собственные.
Жду Yii 3!

ikarushka
Сообщения: 39
Зарегистрирован: 2010.11.23, 15:49

Re: Изменение порядка отображения

Сообщение ikarushka »

mc-bear Спасибо за ответ. Вобщем-то все и прояснил.
На счет валидации последовательности. Если делать возможность для пользователя поднять и опустить позицию, скажем с помощью drag'n'drop, то важно, мне кажется, чтобы не было случаев 1, 3, 4 или 1, 3, 3.

При добавлении новой записи, лучше все-тки использовать MAX, тогда избежишь случаев 1,3,3

Про валидации последовательности у меня еще такой вопрос. Понятно, что ее надо будет отслеживать при удалении записи и после удаления переписывать значения поля position для каждой записи. Можно удалять категори, подкатегории, товары и тд и тп. Для каждой сущность свой контроллер, следовательно свой actionDelete. Как сделать так, чтобы не писать каждый раз в различных actionDelete код этой проверки.

Я старый быдлокодер и только въезжаю в ООП и у меня пока постоянные затыки на элементарных местах.

Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Изменение порядка отображения

Сообщение slavcodev »

в моделях есть событие onAfterDelete(), ищи в мануале.
Жду Yii 3!

Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Изменение порядка отображения

Сообщение slavcodev »

если нужно перемещать последовательность, тогда поле где хранить идишку следующей модели
тогда при перетаскивании нужно будет только поменять эти идишки у трех моделей
Жду Yii 3!

ikarushka
Сообщения: 39
Зарегистрирован: 2010.11.23, 15:49

Re: Изменение порядка отображения

Сообщение ikarushka »

onAfterDelete() - понял, копаю
Поясни последнее. Айдишки то зачем менять? Они постояны - меняем только position. Или ты про перетаскивание субкатегории из одной категории в другую? Это кстати, тоже надо посоображать как делать.

Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Изменение порядка отображения

Сообщение slavcodev »

не ИД модели менять! именно position, только в него уже нужно ставить ИД предстоящей модели.
Жду Yii 3!

ikarushka
Сообщения: 39
Зарегистрирован: 2010.11.23, 15:49

Re: Изменение порядка отображения

Сообщение ikarushka »

Нет не могу понять. Нарисовал себе схемы - все равно не понимаю зачем надо "связывать" id и position. id никогда не меняется, а значение position может быть любым. Если будет время и желание - объясни подробнее.
С событиями вроде разобрался - мощная вещь. Спасибо

ikarushka
Сообщения: 39
Зарегистрирован: 2010.11.23, 15:49

Re: Изменение порядка отображения

Сообщение ikarushka »

Просто я думаю делать как то вот так: http://habrahabr.ru/blogs/jquery/70837/#comment_2031446. Другой способ пока не вырисовывается

georgedrive
Сообщения: 21
Зарегистрирован: 2011.05.14, 03:10

Re: Изменение порядка отображения

Сообщение georgedrive »

из ядра одной движки

к примеру опустить по списку вниз если сортировка ASC (от меньшего к большему)

находим запись с весом (поле weight отвечает за позицию в сортировке и по умолчанию равно id) большим чем запись , т.е. выбрать все записи с большим весом сортируя по ASC и выбрать из этого первую строчку. Далее просто меняем значения местами у исходной записи и полученной

Все просто и легко:

рабочий код

// поднимает по списку вверх
function rc_down($id,$field = 'weight'){
if ($this->desc != 'desc') {
// вес нужно уменьшить
$this->rc_swap_weight_asc($id,$field);
} else {
// вес нужно увеличить
$this->rc_swap_weight_desc($id,$field);
}
}

// опускает по списку вниз
function rc_up($id,$field = 'weight'){
if ($this->desc != 'desc') {
// вес нужно увеличить
$this->rc_swap_weight_desc($id,$field);
} else {
// вес нужно уменьшить
$this->rc_swap_weight_asc($id,$field);
}
}


// if desc == desc
// Обменивает вес указанного элемента с элементом имеющего наибольший вес среди
// элементов с меньшим весом
function rc_swap_weight_desc($id, $field) {
//echo 'rc_swap_weight_desc';
//die();
$cur_line = $this->rc_get_record($id);
$query = "
SELECT
*
FROM
".$this->doc_type."
WHERE
`$field` < ".$cur_line['weight']."
and
(rasdel='".$this->rasdel."') ".($cur_line['parent']!=''?" and (parent='".$cur_line['parent']."')":'')."
ORDER BY
`$field` DESC
LIMIT 1
";
$res = mysql_query($query) or die("up: ".mysql_error());
if (mysql_num_rows($res)>0) {
$row = mysql_fetch_array($res);
$query = "update ".$this->doc_type." set `$field`=".$row[$field]." where id=".$cur_line["id"];
$res = mysql_query($query) or die("смена веса вышестоящей строки: ".mysql_error());
$query2 = "update ".$this->doc_type." set `$field`=".$cur_line[$field]." where id=".$row["id"];
$res = mysql_query($query2) or die("смена веса текущей строки: ".mysql_error());
}
}

// if desc == asc
// Обменивает вес указанного элемента с элементом имеющего наименьший вес среди
// элементов с большим весом
function rc_swap_weight_asc($id, $field) {
//echo 'rc_swap_weight_asc';
$cur_line = $this->rc_get_record($id);
//$query = "select * from ".$this->doc_type." where `$field` > ".$cur_line[$field]." and ((rasdel='".$this->rasdel."') and (parent='".$cur_line['parent']."')) order by $field asc limit 1";
$query = "
SELECT
*
FROM
".$this->doc_type."
WHERE
`$field` > ".$cur_line['weight']."
and
(rasdel='".$this->rasdel."') ".($cur_line['parent']!=''?" and (parent='".$cur_line['parent']."')":'')."
ORDER BY
`$field` ASC
LIMIT 1
";
//echo $query;
//die();
$res = mysql_query($query) or die("up: ".mysql_error());
if (mysql_num_rows($res)>0) {
$row = mysql_fetch_array($res);
$query = "update ".$this->doc_type." set `$field`=".$row[$field]." where id=".$cur_line["id"];
$query2 = "update ".$this->doc_type." set `$field`=".$cur_line[$field]." where id=".$row["id"];
$res = mysql_query($query) or die("смена веса вышестоящей строки: ".mysql_error());
$res = mysql_query($query2) or die("смена веса текущей строки: ".mysql_error());
}
}

Аватара пользователя
coder
Сообщения: 139
Зарегистрирован: 2010.04.09, 23:42
Откуда: Москва

Re: Изменение порядка отображения

Сообщение coder »

Ну, проблемы особо-то и нет. В grid-view можно добавлять свои кнопки и навешивать события. Потом в контроллере добавить действие move. А дальше дело техники - выбирать предыдущий/следующий объект по order и менять этот order местами. Ну, а пересчет сортировки (например при удалении), как говорилось выше, навешивать на стандартные события.

Ответить