Последнее время активно изучаю Yii Framework, которым весьма доволен. Однако, как всегда это бывает, чего-нибудь да не хватает в готовом решении. В моем случае, возникла потребность в оперировании иерархически упорядоченными данными, иначе - деревом. В Yii есть дерево, но мне оно по некоторым причинам не подошло и пришлось сделать свое.
Критерии:
- Источник данных - база данных mysql.
- Данные должны располагаться в одной таблице (можно и больше, но мне и одной хватило).
- Иерархичность должна обеспечиваться одним полем записи - ParentID (в моем случае - pid).
- Таблица данных должна формироваться на стороне mysql (хранимая процедура).
- Результат должен быть представлен в виде дерева похожего на "аккордеон".
- У каждой записи должен быть доступен набор команд.
Внешний вид, который планировалось получить и который получился в итоге:
Widget получил название AlxdDataTree. Позволяет отобразить упорядоченный иерархический набор данных в виде раскрываемого как "аккордеон" дерева.
Входные данные для AlxdDataTree:
- Данные должны передаваться в AlxdDataTree в виде массива записей упорядоченных так, как они будут отображаться в дереве.
- Обязательно должны присутствовать поля: id - идентификатор; title - наименование, которое будет отображаться в дереве; level - уровень записи в дереве; count - количество записей в родителе.
- Перечень доступных команд для записей должен описываться в виде массива.
Прежде всего, мне потребовалось создать таблицу и написать хранимую процедуру для получения данных, которые будут переданы контроллеру, а позже -
AlxdDataTree.
Таблица получила название classificator. Вот ее перечень полей:
Описание полей:
id - уникальный идентификатор каждой записи
pid - идентификатор родителя
oid - идентификатор владельца классификатора
code - системное имя классификатора
name - наименование классификатора
createtime - дата создания записи
modifytime - дата изменения записи
Пример хранимых данных:
Следующим шагом стало написание хранимой процедуры. Мне понадобилось две хранимые процедуры. Первая используется рекурсией, вторая вызывается из контроллера и возвращает конечный результат.
Первая процедура получает на входе id родителя и его текущий level. Вторая процедура получает на входе oid владельца классификатора. Если владелец как таковой не нужен, можно удалить соотв. поле oid из таблицы и убрать входной параметр oid. Разумеется, придется поправить и сами процедуры.
Результат выполнения процедуры Call getClassificators(1):
Затем создал модель classificator с помощью Gii и контроллер с CRUD операциями. В коде действия Admin добавил следующее:
$classificators = Yii::app()->db->createCommand('call getClassificators('.$oid.');')->queryAll();
$this->render('admin',array(
'classificators'=>$classificators,
));
где, $oid - идентификатор владельца классификатора.
Как следствие, надо пришлось поправить и файл вида admin.php. Удалил в нем widget создающий CGridView. Добавил следующее:
$this->widget('ext.AlxdDataTree.AlxdDataTree', array(
'data'=>$classificators,
'idField'=>'id',
'titleField'=>'name',
'levelField'=>'lvl',
'countField'=>'cnt',
)
);
Как видно, AlxdDataTree расположен в каталоге extension в папке AlxdDataTree. Вот так:
Результат работы приложения:
Вот и все!
А вот и AlxdDataTree со всеми стилями, скриптами, картинками и sql-запросами. Никакой регистрации приложения в Yii не требуется, достаточно просто распаковать архив в папке extension. Файлы sql исключительно для примера и на работу самого widget'а не влияют. Каждый может написать свою процедуру для получения конечной таблицы данных.
Неплохо, вот только зачем тут хранимки не сильно понятно.
ОтветитьУдалитьВарианты решений для получения таблицы с данными в описанном формате могут быть разные. Каждый выберет свой. Я показал тот, который считал приемлемым для себя :) В теме главный widget, а не выборка :)
ОтветитьУдалитьКак с вами связаться? Вопрос про контакты
ОтветитьУдалитьМожно писать на почту anotherbad@mail.ru
Удалить