Pull to refresh

Comments 15

Иерархия содержит достаточно много узлов и уровней.
Кол-во узлов может достигать десятки и сотни тысяч.

Пример, который нашел тут
выводит это сразу на экран.
Как мне показалось, основное назначение плагина — это сортировка, изменение и запоминание положения
узлов достаточно небольшой иерархии, которая может быть выведена на экран.

Что, соответственно, не подходит.
Нужно выбрать какой-то конкретный узел и записать его в карточку документа.

В карточке присутствуют много полей разного типа, кроме иерархического.
Поэтому нужно максимально компактно
Хм, nested sets позволяет решить все Ваши поставленные задачи. При этом нет надобности городить велосипед.

Всё делается одним запросом к хранилищу.
Причем довольно простым. Но тут есть вопрос, насколько часто модифицируется дерево и каким количеством человек.
Согласен.

Но насколько я понял по скринам автора, у него в основном производятся операции вывода дерева/ветки/вершины. Для этого, как Вы прекрасно понимаете, nested sets подходят замечательно.
А чем вызван выбор именно динамических селектов?
Можно же было использовать древовидные структуры, кода получилось бы меньше, да и готовые плагины для того же jQuery легко можно найти (вот, например).

А так смотрится конечно мощно, но как-то монструозно.
Динамика нужна, чтоб разгрузить систему и клиента (браузер)
узлов достаточно много (около сотни тысяч).

Система за раз подгружает только один уровень,
выполняя в базе запрос, используя индексы, поэтому небольшой кусочек таблицы возвращает очень быстро.

И очень важным оказалось требование к компактности интерфейса.

Поле такого типа является частью карточки документа,
составленной из различных полей.

К тому же, если кол-во «детей» в узле велико, то сложно читается полный путь к узлу для оператора
Например:
Узел 1 (выбран)
=> Узел 2
=> Узел 3
=> Узел 4

=> Узел N (выбран)

Или:
Узел 1 / Узел 6
Простите.
«Система за раз подгружает только один уровень»:
только при выборе очередного узла.

При инициализации загружается родительский узлы и все дети (этих узлов) на один уровень.
То есть, если инициализирующий узел вложен на 5 уровней, то будут собраны 5 ComboBox-ов — они же «select» — ы

но в все это в фоне.
Если инициализирующий элемент не является «листом» дерева, то подгружается еще список узлов, подчиненных этому, чтоб оператор мог продолжить спускаться по дереву от инициализирующего узла.
Я все понимаю, но сути дела это не меняет. Вы могли рассмотреть нечто подобное этому. К слову, подгрузка дерева в этом примере тоже происходит по уровням, в этом нет ничего необычного, серверная логика тоже достаточно тривиальная. И я больше, чем уверен, реализаций таких деревьев можно найти массу, да и написать, в общем-то, не сложно.

А у вас получился очень громоздкий велосипед.
Я смотрел эти варианты.
Уважаемые хабропользователи, еще раз повторюсь — услышьте меня, пожалуйста.
Основное требование к элементу:
1. компактный
2. можно увидеть весь путь, по которому находится элемент.
3. Задача не в навигации по дереву и понимание его структуры, а именно выбор узла, сохранение выбранного

1. Деревья хорошо подходят для своих задач — когда на экране есть место.
Но если это не так, их приходится размещать в скроллинге и навигация в скроллинге, в котором скрыто 30 пунктов становится сложной.

2. Внутри иерархий есть одноименные узлы, например узел «Ленинградский проспект»
и недостаточно видеть узел, нужно видеть всю цепочку и без скроллинга и в компактном виде. нужно видеть ничего оператору не даст при отображении в таком виде:
-> родитель родителя (тоже скрыт за скроллом)
-> родитель (скрыт за скроллингом)
->… (30 строк)
-> Ленинградский проспект

3. Если сохранить выбранный узел в предложенном вами решении, то для того, чтоб показать выбранный, нужно развернуть иерархию снизу до самого верха. Это занимает много места. Хорошо, если оно есть. Но у меня другая ситуация.

Все это делает эти элементы неприменимыми для этой конкретной задачи.

Я не в коем случае, не настаиваю на универсальности этого отображения.
Я говорю, что для некоторых (соответствующих описанным требования) задач, этот вариант более подходит.

Это просто одна из альтернатив предложенных вами решений. Не лучше и не хуже — просто другая.
А возможность выбора — это всегда хорошо — кому-то пригодится (собственно, уже пригодилась паре человек, которых нет среди хабраюзеров).

Возможно, их много, а может быть, именно этого варианта нет среди них (все, которые я нашел, были именно разворачиванием деревьев).

Я не претендую на особую сложность и необычность серверной логики и не говорю, что это сложно написать (написал за 2 часа «с нуля»)
просто хочу предложить хабрасообществу и всем, кто набредет на статью, еще одну из альтернатив, которая может подойти кому-то для каких-то специфических задач больше.

А кому-то, конечно, не подойдет. И это нормально
P.S.
2. Этим решением, иерархия будет выглядеть как:
Россия / Москва / Ленинградский проспект

С возможностью быстро изменить путь, не вызывая модельные окна.
Основное требование — компактность

Очень компактно и сразу понятен и виден весь путь.
Делалось это для составления карточки документа в системе документооборота,
в которой около 30 полей.
Если не экономить место, пользователь вынужден часто пользоваться скроллом.
Можно работать с предложенным вами решением в отдельном модальном окне — это тоже вариант.
Кому-то подойдет он, — удачное решение для своих задач.
Простите, но что это?
        $num = 0;
        do {
            if($num > 1000)
            break;
            ...
            $num++;
        }
        while($isParentFind);
Спасибо, исправил.
Не вычищенный мусор.

Такая логика приведена тут только для иллюстрации и специфична для используемой (тестовой) структуры данных, — чтобы пример не был привязан к СУБД.
Но, тем не менее, добавил дополнительный комментарий.
Это был частный случай, вы используете класс, как пространство имен для ваших методов.

Пример было бы намного более приятно использовать, если бы Вы:

1. выделили в отдельный интерфейс работу с данными, н-р:
namespace HerarhySelect;
interface DataSource
{
    public function getParentSiblings($itemValue);
    public function getSiblings($itemValue);
}


2. вынесли html-представление в отдельный файл или так же в помощник и убрали бы оттуда всяческие вхождения javascript, привязавшись только к классам при помощи .live() или реинициализации после ajax-подгрузки.

3. JavaScript оформили бы в виде плагина jQuery (это не сложно), раз уж Вы все равно используете этот фреймворк.
Конструктивно, займусь, выложу update сюда.
Sign up to leave a comment.

Articles