UniTree - как реализовать универсальное дерево?

В getTables и затем в PVTables получилось реализовать универсальный компонент для таблиц. Где в несколько инструкций описываешь таблицу, а компонент уже ее реализует. Для полноценного сайта нужны не только таблицы, а еще и формы, файл-менеджер и деревья. Сейчас опишу то, что хочу от деревьев. Возможно, кто-нибудь подскажет как это проше и грамотнее реализовать.

В админке MODX реализовано 3 дерева: ресурсы, категории и файлы. Фактически, для того, чтобы использовать данные типа дерева в MODX, например, структура компании, приходиться использовать ресурсы MODX. Не используя ресурсы сложно реализовать редактирование дерева. Но хорошо если таблица ресурсов небольшая, а если в ней много строк, то тормозить будут все элементы сайта завязанные на ресурсы. Но все в ресурсы пихать не хочется. Хочется иметь форму редактирования дерева для произвольной таблицы в базе. С перетаскиванием элементов дерева. С созданием и удалением.
Также хочется сделать такой компонент, чтобы составил краткое описание и компонент автоматом сделал нужное дерево. То есть, чтобы не приходилось писать на каждое дерево кучу процессоров, как требуется в ExtJs.
Так же интересно, чтобы один объект можно было поместить в разные папки.
2 года назад, в getTables, я начал делать подобный модуль.

{'getTree' | snippet : [
    'showLog'=>1,
    'name'=>'itr_products',
    'loadModels'=>'gtsshop,naryadflow',
    'selects'=>[
        'template'=>[
            'type'=>'autocomplect',
            'pdoTools'=>[
                'class'=>'modTemplate'
            ],
        ],
        ...
    ],
    'tree'=>[
        'rootIds'=>'gtsshop_p_catalog' | option,
        'onclick'=>[
            'action'=>'gtsshop/getpages',
        ],
        'showUnpublished'=>1,
        'actions'=>[
            'create'=>[
                'classes'=>[
                    'gsCategory'=>[
                        'label'=>'Создать категорию продукции',
                        'processors'=>['gsCategory'=>'resource/create'],
                        'parent_class'=>'modResource,gsCategory',
                        'default_template'=>'CatalogTemplate',
                    ],
                   ...
                ],
            ],
            'copy'=>[
                'classes'=>[
                   ...
                    ],
                ],
                
            ],
            'remove'=>[],

        ],
    ]
]}
Но первая проблема — это то что пришлось использовать ресурсы, так как pdoTools может делать дерево только для ресурсов ($modx->getChilds только для ресурсов). Потом не хватило времени сделать перетаскивание. И дизайн дерева не очень получился.

Сейчас хочется реализовать дерево уже на основе Vue в PVTables. Использовать думаю https://github.com/holiber/sl-vue-tree.
Самое интересное думаю структура базы данных дерева UniTree:
Таблица, например, Дерево продуктов
id, parent_id, parents_ids, title, class_key, target_id
1, 0,, Главная, modResource,1
2, 1,#1#, Категория 1,modResource,2
3, 1,#1#2#, Продукт 1,gsProduct,1
4, 1,#1#, Категория 2,modResource,3
5, 1,#1#4#, Продукт 1,gsProduct,1

То есть, можно хранить информацию о дереве(id, parent_id, parents_ids) в одной таблице, а объекты в других таблицах (modResource, gsProduct и т.д.). Тогда можно один объект (gsProduct,1) вкладывать в разные категории (Категория 1, Категория 2).
parents_ids предназначен для того, чтобы не приходилось использовать $modx->getChilds. Для parents='2,4' пишем запрос select * from treeProducts where parents_ids LIKE '%#2#%#4#%'
Такая структура несколько усложнит класс работы с деревом, но думаю позволит написать универсальный класс для любых деревьев. Только если parents_ids это varchar 191, то вложенность категорий будет ограниченна.

Быстродействие
В админке MODX, дочерние ресурсы подгружаются каждый раз когда раскрываешь категорию. Для дерева с элементами меньше 1000 проще подгрузить сразу все дерево. Но если браузер начинает отрисовывать много элементов, то он начинает тупить. Миллион элементов он будет грузить долго.
Но vue элементы в браузере сразу не отрисовывает. Свернутые элементы не будут отрисованы, а просто объект js миллион элементов вроде держит не напрягаясь. То есть возможно имеет смысл загрузить все дерево сразу для Vue. Надо сделать большую базу и тестировать скорость. В том числе как быстро база отдает миллионы строк.

Я кустарь-одиночка-самоучка и многово в программировании не знаю. Реализовать такой компонент мне кажется интересным и разумным. Но может я где-то не прав и где-то ошибаюсь. Будет интересно узнать ваше мнение.
Александр Туниеков
08 марта 2025, 02:46
modx.pro
72
0
Поблагодарить автора Отправить деньги

Комментарии: 0

Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
0