
Достаточно распространенная задача — поменять местами элементы в списке. Но как правило эта задача решается жуткими костылями, особенно если это Drag&Drop.
Сейчас я расскажу вам очень простой и гибкий способ сделать это, используя Marionette.js и jQuery UI Sortable.
Подключаем jQuery UI
Из jQuery UI нам потребуется только часть Sortable, поэтому, экономии трафика ради, я смело снял за вас все ненужные галочки отсюда. Вам осталось только загрузить.
Обратите внимание
В коде ниже используется ссылка на Marionette
var Marionette=Backbone.Marionette;
Создаем шаблон поведения
Данную функциональность мы реализуем в виде Behavior, о котором я писал ранее.
Вот код поведения, который будет отвечать за возможность сортировки моделей внутри коллекции
Behaviors.Sortable=Marionette.Behavior.extend({ onRender:function(){ var collection=this.view.collection // Замыкаем коллекцию ,items=this.view.children._views // Получаем список дочерних элементов ,view ; for(var v in items){ view=items[v] view.$el.attr('data-backbone-cid',view.model.cid); // Привязываем элемент к модели по cid } this.$el.sortable({ // Делаем список сортируемым axis: this.options.axis||false, grid: this.options.grid||false, containment: this.options.containment||false, cursor: "move", handle:this.options.handle||false, revert: this.options.revert||false, update: function( event, ui ) { var model=collection.get(ui.item.data('backbone-cid')); // Получаем привязанную модель collection.remove(model,{silent:true}); // По-тихому удаляем её из коллекции collection.add(model,{at:ui.item.index(),silent:true}); //И также втихаря добавляем её по нужному индексу } }); } });
Что это?
Этот шаблон поведения предназначен для CollectionView. Он дожидается события onRender, после чего привязывает каждый элемент ItemView к его модели с помощью cid.
Потом мы разрешаем этому списку сортироваться с помощью Drag&Drop используя jQuery.
Опции Sortable
Для каждого вида можно передавать свой набор опций, подробнее можно прочитать в документации jQuery UI. В представленном выше коде реализованы не все возможные опции, вы можете добавить свои по желанию.
Сортировка
Когда один из элементов перетащили, мы удаляем привязанную к этому элементу по сid модель из коллекции и добавляем заново по нужному индексу. Флаги silent:true нужны, что бы Marionette.js не пыталась переставить все по-своему, у неё это плохо получается.
Соединяем СollectionView и Behavior
Теперь применим это в действии
var IView=Marionette.ItemView.extend({// Создаем стандартный ItemView template:'#item-template' }) var CView=Marionette.CollectionView.extend({// Создаем CollectionView itemView:IView, behaviors: {// вот тут творится вся магия. Sortable:{// Применяем поведение Sortable к данному виду. //В качестве примера я передал параметр containment containment:'parent' // Теперь перетаскивать элементы мы можем только внутри родительского контейнера. } } })
Теперь вы с помощью одной строчки behaviors: {Sortable:{}} можете добавить возможность Drag&Drop сортировки CollectionView.
Как сохранить это на сервер?
Я не знаю в каком виде на сервере у вас хранится порядок сортировки, но с помощью описанного выше подхода вы сможете передать порядок в любом формате.
Я использую MongoDB, поэтому без особых проблем с помощью сollection.toJSON() отправляю это на сервер Node.JS и сохраняю как есть.
Можно отправить на сервер упорядоченный массив id, получить который можно с помощью
collection.pluck('id');
Вот и всё
enjoy it works!
Надеюсь статья вам помогла.
Пожалуйста, пишите в комментариях о чем вам хотелось бы ещё почитать.
