Как стать автором
Обновить

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

Добавьте ваш модуль на ngmodules.org/, там многие плагины размещены. Мне когда было необходимо найти было удобное решение для драг-дроп сортировки, вашего не было, а оно вполне удобное.

Хотя и лучше использовать директивы.
Прочитал документацию. Насчет директив ошибся. Все есть.
Нет, вы не ошиблись, обязательно добавлю.
ngmodules.org/modules/Sortable — вот теперь добавил, только не понял как там пример добавить, github markdown ```html .... ``` не работает.
А что с emberjs? Сложно ли его на нем завести?
С Ember нет опыта, задача висит, так что пока ничего не могу сказать, будет время, постараюсь изучить, как там создавать подобные компоненты.
Баг в демке (и, видимо, в либе) — если вниз перетащить первый элемент, то он вставляется посередине, а не в конец.
В какой именно демке? (со список работает корректно recordit.co/FNOX4Sg2ax)
Проявляется не сразу, а после того как погонять элементы туда-обратно. Сафари, мак. Записал видео: www.dropbox.com/s/eus4ukm7o4our2i/bug.mov?dl=0
Занятно, похоже в директиве есть проблема.
Пока не могу добиться такого поведения даже в Сафари, вечером посмотрю внимательней, спасибо за отзыв.
Если один из списков оставить без элементов, то в него перетащить элемент уже не получится?
Получиться, нужно только не забыть задать минимальную высоту.
Система расширений (например вложенные списки)

Эта фича очень бы пригодилась. Недавно проверял — нет ни одной реализации иерархических сортировочных списков, которая бы без проблем заводилась на meteor. Поэтому ваше внимание к этому фреймворку внушает надежды.
Спасибо!
Буду с нетерпением ждать систему расширений.
Лазать по DOM`у в поисках модели, да ещё и комментариях, которые оставляет angular — это просто жесть.
Если уж и хотите уделать зубров (которые не додумались до такого), примите как совет:
<ul ng-sortable="item in items" options="sortableOptions">
    <li>{{ item }}</li>
</ul>


P.S. Я таким образом dropdown для css фреймворка делал.
<dropdown items="item in items" default-text="select items" on-select="onSelect(item)">
    {{item.description}}
</dropdown>
Я так не считаю, даже наоборот. Во-вторых не по DOM, а по scope, это нормальный способ, непротиворечащий концепции ангуляра. В-третьих, у модуля четкая зона отвественности, он только дает возможность сортировки, не более и не забирает на себя возможности ng-repeat, что на мой взгляд намного хуже.
Может я не правильно выразился, но…
var ngRepeat = [].filter.call(el.childNodes, function (node) {
     return (
           (node.nodeType === 8) &&
           (node.nodeValue.indexOf('ngRepeat:') !== -1)
        );
  })[0];


… разве это не лазить по DOM`у в поисках модели (её имени)?

и потом…
// Прасим название переменных элемента и массива
  ngRepeat = ngRepeat.nodeValue.match(/ngRepeat:\s*([^\s]+)\s+in\s+([^\s|]+)/);

Согласен, можно назвать это манипуляцией, но этот код выполняется на стадии компиляции, тут не итоговый DOM, как как только в ангуляре появится более элегантная возможность (я не нашел) получить ссылку на модель, это будет переписано. Но повторюсь, это не нарушает соглашения анугляра, данный код никоим образом не воздействует на DOM, он просто получает данные из мета информации и выполняется разово.
Как насчет многоуровневой сортировки?

Пример: wadmiraal.github.io/jquery-tabledrag/

В свое время потребовалось реализовать такую. Плагин по ссылке чем-то не устроил. В итоге реализовал при помощи вложенных списков jQuery UI Sortable. Пришлось написать много вспомогательного кода, который я так и не покрыл юнит-тестами. А из-за большого количества инстансов Sortable реализация тормозила: на ста элементах становилась неотзывчивой, на тысяче — откровенно тормозила, на десяти тысячах завешивала вкладку Chrome.

И это я уже не говорю про мобильники… Для поддержки перетаскивания пальцем я использовал jQuery UI Touch Punch, который завешивал браузер уже на ста элементах.

Ваш проект — прямо глоток свежего воздуха. Но без вложенных списков от него мало пользы, т. к. с плоскими и jQuery UI сносно справляется.
Это приоритетная задача, надеюсь в феврале успею закончить, время как обычно против меня. Самый выжный вопрос, как именно это всё должно работать, а именно какие базовые возможности нужно заложить.
С точки зрения конечного пользователя, наиболее удачной мне видится реализация tabledrag. Работает четко и предсказуемо. Никогда не возникало нареканий на нее (в отличие от собственной реализации).

С точки зрения разработчика, позаботьтесь о следующих фичах:

  • Сериализация/маршаллинг дерева для сохранения структуры на сервер.
  • Восстановление древовидной структуры из данных, поступивших с сервера.
  • API для манипулирования узлами: перемещение, добавление, удаление, обращение к, поиск. Удаление требуется в двух режимах: с уничтожением всей ветки или с уничтожением одного узла и перемещением дочерних узлов на уровень уничтоженного узла (или в конец списка).
  • Возможность включения отображения кнопок, позволяющие перемещать узлы тапом, а не перетаскиванием. Это весьма актуально для больших деревьев: проблематично переместить узел перетаскиванием, когда ближайшая ячейка находится за пределами экрана.
  • При перетаскивании ветки его плэйсходлер должен по размеру соответствовать одинарному узлу, а не перетаскиваемой ветке, иначе таскать большие ветки станет практически невозможно.
  • Возможность сворачивания/разворачивания веток. При drag over свернутой ветки в течение двух секунд она должна разворачиваься автоматически.
  • Широкий набор событий на все случаи жизни.
  • Возможность удобно навешивать колбэки на эти события.

Для начала, думаю, хватит. :)

И обязательно покройте весь код тестами: юнит-тестами для тестирования методов по отдельности, а также интеграционными тестами для тестирования методов в совокупности.

PS При юнит-тестировании тестируйте методы в изоляции, то есть если метод А запускает метод Б, то при тестировании метода А код метода Б выполняться не должен! Для этого метод Б должен поступать в метод А в качестве аргумента. При нормальной работе кода, метод А берет метод Б из дефолтного значения аргумента. А при тестировании, в качестве метода Б в метод А передается метод-заглушка, созданный при помощи Sinon.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации