Marionette.js. Drag&Drop сортировка моделей в коллекции

в 21:19, , рубрики: backbone, backbone.js, drag and drop, javascript, jquery, jQuery UI, marionette, Веб-разработка, метки: , , , ,

Marionette.js. Drag&Drop сортировка моделей в коллекции

Достаточно распространенная задача — поменять местами элементы в списке. Но как правило эта задача решается жуткими костылями, особенно если это 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!
Надеюсь статья вам помогла.
Пожалуйста, пишите в комментариях о чем вам хотелось бы ещё почитать.

Автор: pharrell

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js