Иногда попадаются интересные задачи, которые сложно написать с первого раза. Одной из таких задач оказались каскадные списки и легким комментарием я прикинул, что на Backbone у меня получится написать короче.
Короче не получилось… Отчасти из-за того, что я усложнил задачу до бесконечно выпадающих списков и из-за небольшой многословности Backbone.
Немного подумав в голове появляется примерно такая блок-схема:

При проектировании интерфейсов я всегда начинаю с самых мелкий деталей, в случае списка — это option и представление
Задача стоит сделать бесконечно сложенные списки и для её решения можно применить что-то вроде связного списка для HTML:
В контейнер
Спустя почти два часа я получил примерно такую демку. Код довольно простой и понятный, я не нашел того, что можно там долго объяснять.
1. Чтобы не вспоминать у каких элементов есть вложенный список, в конструкторе модели
2. После изменения выбранного элемента нужно найти модель, которая за него отвечает. Для решения задачи пришлось сделать массив
3. Вышеприведенный код посылает сигнал
Весь код находиться в такой обёртке:
Обычно я пишу обертку чуть посложней, но в данном случае весь код находится в одном файле и этого достаточно. Заранее не прошу не критиковать сокращения, мне так удобней и читается проще, чем всякие доллары и нижние прочерки.
Каждый раз, когда работаю с Backbone, радует аккуратность полученного кода. Хотя, возможно, это лишь для меня он получается аккуратный?
Короче не получилось… Отчасти из-за того, что я усложнил задачу до бесконечно выпадающих списков и из-за небольшой многословности Backbone.
Рисуем две окружности...
Немного подумав в голове появляется примерно такая блок-схема:

При проектировании интерфейсов я всегда начинаю с самых мелкий деталей, в случае списка — это option и представление
SelectItemView, которое его рендерит. Далее элементы образуют список, а списки образуют то, что нам нужно — базовое представление BaseView.Задача стоит сделать бесконечно сложенные списки и для её решения можно применить что-то вроде связного списка для HTML:
<script type="text/template" id="base-tempate"> <div class="primary"><!-- SelectView --></div> <div class="secondary"><!-- вложенный BaseView, если нужен --></div> </script>
В контейнер
.secondary будут рекурсивно вкладываться дочерние списки, а при изменении активного элемента .primary будет происходить очистка .secondary и рендер нового списка.… И дорисовываем остальную сову
Спустя почти два часа я получил примерно такую демку. Код довольно простой и понятный, я не нашел того, что можно там долго объяснять.
Интересные моменты
1. Чтобы не вспоминать у каких элементов есть вложенный список, в конструкторе модели
ItemModel происходит добавление значка ">" к метке:initialize: function(){ if(this.get('items').length > 0){ this.set('label', this.get('label') + ' >'); }
2. После изменения выбранного элемента нужно найти модель, которая за него отвечает. Для решения задачи пришлось сделать массив
itemViews представлений элемента, которые были отрендерины:changeItem: function(){ u.each(this.itemViews, function(view){ if(view.el === this.el.options[this.el.selectedIndex]){ this.collection.selectedModel = view.model; this.collection.trigger('changeSelectedItem'); } }, this); },
3. Вышеприведенный код посылает сигнал
changeSelectedItem, который ловит BaseView и пытается отрендерить вторичный список, если есть нужная коллекция:renderSecondary: function(){ var collection = this.collection.selectedModel.itemsCollection; var container = this.$el.find('.secondary'); container.empty(); if(collection) (new BaseView({ collection: collection })).render().$el.appendTo(container); }
Пояснения по коду
Весь код находиться в такой обёртке:
(function(j, b, u){ // j - jQuery // b - Backbone // u - Underscope })(jQuery.noConflict(), Backbone.noConflict(), _.noConflict());
Обычно я пишу обертку чуть посложней, но в данном случае весь код находится в одном файле и этого достаточно. Заранее не прошу не критиковать сокращения, мне так удобней и читается проще, чем всякие доллары и нижние прочерки.
Заключение
Каждый раз, когда работаю с Backbone, радует аккуратность полученного кода. Хотя, возможно, это лишь для меня он получается аккуратный?
