Плагин Ext.ux.HistoryTree — дерево с историей

    Добрый день.
    Хочу поделиться ExtJS плагином Ext.ux.HistoryTree — дерево с историей:
    — для всех переходов по дереву (раскрытие/скрытие ветки, выделение ветки) работают кнопки Назад/Вперед;
    — в URL браузера всегда прямая ссылка на текущее состояние дерева.

    Demo и API

    Совместимость:
    — IE6+ (с определенными ограничениями), FF, Opera, Safari, Chrome;
    — ExtJS версии 2.3.0, 3.2.1 (это все версии, что я тестировала).

    Дерево с историей мне понадобилось для разрабатываемого мной приложения, но потом я решила оформить его в виде плагина. Возможно, кому-нибудь будет полезно.

    Буду рада замечаниям и предложениям по работе плагина.

    Средняя зарплата в IT

    120 000 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 6 007 анкет, за 1-ое пол. 2021 года Узнать свою зарплату
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 29

      +1
      История у вас как-то некрасиво хранится. Все-таки #Group_D/Germany было бы куда веселее.
        +1
        Согласна. Но так короче и универсальнее: если какие-то названия были изменены, то ссылки все равно будут работать.
          0
          А если количество пунктов изменилось, то ссылки уже будут вести не туда?
            +1
            Да, тогда будут вести не туда.
              0
              Следовательно, надо имена, а не индексы.
                0
                И да, идентификаторы гораздо правильнее )))
                  0
                  Идентификаторы в реальных приложениях как правило не намного красивее порядковых номеров :)
          0
          В FF (3.0) под Линуксом постоянно идет обновление страницы. В остальных (opera и chrome) такой проблемы не замечено.
            +1
            Я не поняла, когда идет обновление страницы: при нажатии на Назад/Вперед?
              0
              Самопроизвольно. Т.е. при загрузке страницы на каком-то этапе срабатывает рефреш.
                +1
                Хм. Не знаю, что сказать. Нет Линукса, чтоб проверить. Найду — посмотрю.
                  0
                  Нашла, попробовала. Самопроизвольных рефрешей добиться не смогла.
            0
            не догоняю, а чем стандартная библиотека не устроила? www.extjs.com/deploy/dev/examples/history/history.html
              +3
              В плагине она и используется. Суть плагина в том, что к стандартному компоненту дерево Ext.tree.TreePanel прикручен другой стандартный компонент Ext.History — получилось дерево с историей.
                0
                возможно я сейчас глупость сморожу, но почему просто установку состояния не повесить на fn: это раз, два что будет с состоянием, если использовать сортировки и поиск по дереву? ведь я так понял у вас состояние записывается не кодом id-id-id как рекомендуют extjs а позициями в дереве?
                  +1
                  При изменении состояния url соответственно меняется состояние дерева. На какое fn вы предлагаете повесить установку состояния?
                  Если позиции узлов дерева будут меняться, узлы будут удаляться/добавляться, то ссылки могут оказаться битыми.
                  Как уже писала, порядковые номера вместо idшников я решила использовать для краткости.
                  Но идею замены номеров на idшники — обдумаю :)
              0
              Молодец! Прикольную цяцьку сделала — лови плюсы :)
                –2
                Подсветка — красиво. Многоуровневое дерево почти в конец спрятано — плохо.
                  0
                  Все бы хорошо, но вот это сильно режет глаз (там выше, вроде уже говорилось об этом):

                  «stonejungle.net/extjs/ru/#{»historyTree":{«1»:{},«2»:{},«6»:{},«8»:{«0»:{«sel»:«1»},«1»:{}},«10»:{}}}"

                  Вместо этого стопроцентно нужен адрес: stonejungle.net/extjs/ru/#quarterfinals/first/x/
                  ибо в первую очередь такой список (с историей) именно навигационная штуковина.
                    +1
                    Тогда скорее так:
                    «stonejungle.net/extjs/ru/#{»historyTree":{«Group_A»:{},«Group_B»:{},«Quarterfinals»:{«First»:{},«Second»:{},«selected»:«Second»}}}»
                    Просто через "/" не получится: как тогда, например, показать, что в узле «Quarterfinals» раскрыты 2 узла — «First»и «Second» и выделен «Second».
                      0
                      А нам и не нужно этого показывать. Наоборот, дерево по идентификаторам определяет, что ему и как показывать.

                      Здесь жертвуем ненужной универсальностью и полностью базируем все на соглашениях (conventions).

                      Из "#/quarterfinals/final/x/" список всегда должен знать, что «x» — выбранный пункт, а два предыдущих — открыты. Индекс с идентификаторами загружается на страницу вместе с деревом. Можно индексировать как отдельные кусочки адреса (например, «final»), так и маршруты целиком.

                      Если пользователь только-только зашел на страницу, то ему вообще не нужны «открытые» еще и Group_A, и Group_B. И состояние не нужно хранить в адресной строке — его нужно хранить на сервере и можно загружать, скажем, асинхронно, с помощью JSON.

                      Если пользователь уже на странице, а само содержимое загружается асинхронно — то можете хранить состояние на самой странице (опять же — не в адресной строке), и на дереве это никак не отразится.
                        0
                        А если X — это не лист, то как по такому адресу понять, что X именно выбран, а не открыт?
                        Для хранения состояния дерева на сервере есть плагин от Saki.
                        В моем плагине смысл в том, что состояние хранится в URL: всегда можно дать кому-то ссылку на определенное состояние дерева и перейти Назад/Вперед по истории переходов по дереву.
                          +1
                          «А если X — это не лист, то как по такому адресу понять, что X именно выбран, а не открыт?»

                          Простота — это всегда круто. Не усложняйте. Следуйте соглашениям опять же.
                          Если «x» — не лист, то он по-умолчанию и выбран и открыт, когда человек перешел по ссылке. К тому же, с точки зрения навигации, «папка» вполне может одновременно быть и какой-то «страницей» — то есть такой адрес вполне может содержать некоторый контент.

                          Просто вопрос в том, что вы хотите достичь — как по мне, лучше сделать просто и покрыть основные сценарии, чем усложнить все, сделав (зачем-то) передачу состояния через ссылку, что на практике если и будет использовано — то очень редко.
                    0
                    1. URL более красивый хотелось бы, либо тогда заенкодить его, чтобы просто уникальный был. JSON пугает.

                    2. JsLint Вам в помощь — меолчь, а неприятно:
                    if(this.encodeValue(newState) == "")
                    this.fireEvent('statechange', this, "", newState);
                    else
                    for (element in newState)
                    if (this.encodeValue(newState[element]) != this.encodeValue(previousState[element]))
                    this.fireEvent('statechange', this, element, newState[element]);

                    Где ж тута скобочки? :) Как такой код читать?
                      0
                      Спасибо. Учту.
                      0
                      Зачем лицензия GPL? Для таких вещей самое то использовать BSD.
                      Прикольно конечно, но не вижу практической ценности. Плюс к тому такие вещи намного легче поддерживать, если они лежат на гитхабе или гуглкоде, в плане контроля версий и в плане фидбека.
                        0
                        а ещё есть LGPL, который тоже «для таких вещей» вполне подойдёт.
                          0
                          Про GitHub и Google Code — решила сначала выложить как есть, а потом, если кого-то заинтересует плагин, перенести на Google Code.
                          0
                          Можете показать пример кейза, когда действительно надо при назад-вперед в браузере состояния дерева разворачивать? оО

                          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                          Самое читаемое