Комментарии 84
еще один минус сортировки на клиенте — вынос бизнес логики с сервера. как будете сортировать даты, например, если приложение поддерживает разные форматы?
ваш способ не подходит для реальных приложений.
ваш способ не подходит для реальных приложений.
Мой пример достаточно легко нарастить так, чтобы поддерживались разные форматы даты. При выводе ведь все равно известно, какой формат даты будет в колонке. Я бы сказал, что способ подходит для реальных приложений, но, конечно, не стоит пихать его направо и налево.
хм… при выводе это известно только на сервере. на клиенте — нет.
01/02, 02/01 — как вы на клиенте узнаете, в каком порядке должны следовать эти даты?
единственный способ — передавать используемый формат на клиента, что увеличивает связанность кода.
давно уже есть техника ajax, тут ей самое применение.
01/02, 02/01 — как вы на клиенте узнаете, в каком порядке должны следовать эти даты?
единственный способ — передавать используемый формат на клиента, что увеличивает связанность кода.
давно уже есть техника ajax, тут ей самое применение.
Автор писал «Плюсы — отсутствие перезагрузки страницы». AJAX, принимая во внимание факт, что реальная табличка весит в разы больше остального интерфейса, по сути — перезагрузка страницы.
что Вам мешает указать клиентской логике в каком формате дата?
появится (к примеру) переменная var dateFormat = 'm/d' (или d/m) и в зависимости от этого сортируем нужным способом (или мне Вам рассказать как преобразовать дату в JS?)
появится (к примеру) переменная var dateFormat = 'm/d' (или d/m) и в зависимости от этого сортируем нужным способом (или мне Вам рассказать как преобразовать дату в JS?)
меня уже так за это мнение заминусовали, что мне уже страшно :)
вы правы, так можно сделать. но зачем иметь две логики и на клиенте и на сервере?
вы правы, так можно сделать. но зачем иметь две логики и на клиенте и на сервере?
А какая тут бизнес логика? Тут только представление информации.
что значит какая? правила сортировки — это бизнес логика («несложная»). представление информации — это вывод уже отсортированных значений.
хоть и допускается вынос несложной бизнес логики на уровень терминала, но по моему личному опыту это можно делать разве что на домашних страничках.
хоть и допускается вынос несложной бизнес логики на уровень терминала, но по моему личному опыту это можно делать разве что на домашних страничках.
Вам понятно значение слова «бизнес»?
Сортировка — это не бизнес-логика.
Сортировка — это не бизнес-логика.
да, мне понятно значение этого слова.
привожу пример: вывод списка документов (в сферической cms), отсортированных по статусу. сначала идут Draft, потом Work In Progress, потом Final. это бизнес логика. потому что при переводе на русский порядок не поменяется.
вы можете расширить этот пример на все случаи сортировки.
при разработке нужно всегда быть готовым к новым бизнес требованиям. а код, который тут приведен, к ним не готов.
если вы поняли, что я вам тут говорю, почитайте про трехуровневую архитектуру, хотя-бы тут ru.wikipedia.org/wiki/Трёхуровневая_архитектура
а если не поняли, то не утруждайтесь.
привожу пример: вывод списка документов (в сферической cms), отсортированных по статусу. сначала идут Draft, потом Work In Progress, потом Final. это бизнес логика. потому что при переводе на русский порядок не поменяется.
вы можете расширить этот пример на все случаи сортировки.
при разработке нужно всегда быть готовым к новым бизнес требованиям. а код, который тут приведен, к ним не готов.
если вы поняли, что я вам тут говорю, почитайте про трехуровневую архитектуру, хотя-бы тут ru.wikipedia.org/wiki/Трёхуровневая_архитектура
а если не поняли, то не утруждайтесь.
Приведенный пример некорректен. В теме обычная таблица, в которой данные равнозначны. Да и в вашем пример должна быть опция — по-другому сортировать.
В нашем приложении например пользователи сами могут для каждой таблицы настраивать свои сортировки, как им удобнее. Вы будете утверждать, что у наших пользователей разные бизнес-логики?
В нашем приложении например пользователи сами могут для каждой таблицы настраивать свои сортировки, как им удобнее. Вы будете утверждать, что у наших пользователей разные бизнес-логики?
извините, я умываю руки.
хочется посмотреть на лицо нашего бизнес аналитика, когда я ей скажу сегодня, что сортировка — не бизнес логика.
завидую вам: вы живете в идеальном мире.
хочется посмотреть на лицо нашего бизнес аналитика, когда я ей скажу сегодня, что сортировка — не бизнес логика.
завидую вам: вы живете в идеальном мире.
Гипотетический пример. Допустим один из ваших пользователей(если у вас веб-приложение) поставил себе какой-нибудь хитрый или плагин или скрипт GreaseMonkey, который позволяет сортировать таблички как ему хочется. Изменится ли как-нибудь лицо вашего бизнес-аналитика, когда она об этом узнает?
согласитесь, что такая сортировка в общем случае будет работать неверно, так как сторонний скрипт ничего не знает про структуру отображаемых данных.
в случае установки такого скрипта разработчики не несут ответственности за корректное отображение данных. кроме того, в требованиях к окружению обсуждаются эти вопросы.
представте себе аналитика (пользователь системы), который себе такой плагин себе поставил и отсортировал какие-нить хитрые рейтинги. его просто уволят, если он будет этим пользоваться.
реакция такова: если выяснится, что кто-то у клиентов ставит себе такую штуку, то каждый раз, когда они нам будут постать баг, первым вопросом будет: а не поставили ли вы себе каких-то плагинов.
таковы реалии.
в случае установки такого скрипта разработчики не несут ответственности за корректное отображение данных. кроме того, в требованиях к окружению обсуждаются эти вопросы.
представте себе аналитика (пользователь системы), который себе такой плагин себе поставил и отсортировал какие-нить хитрые рейтинги. его просто уволят, если он будет этим пользоваться.
реакция такова: если выяснится, что кто-то у клиентов ставит себе такую штуку, то каждый раз, когда они нам будут постать баг, первым вопросом будет: а не поставили ли вы себе каких-то плагинов.
таковы реалии.
Реалии действительно таковы. Это правда. Поэтому и пример был гипотетический :)
А если пользователь скопирует ваши данные в эксель и там будет сортировать — это случайно вашу бизнес-логику не затронет? Фактически мы имеем такой пример, что пользователь получил данные и хочет их смотреть так, как ему хочется. Всякие аналитики это любят очень(не которые «бизнес-», а другие).
Ну в общем ладно. спор пустой. Я просто считаю, что сортировать для удобства пользователя можно даже совершенно не представляя что за данные сортируем(все хорошие гриды это делать умеют). И в таком случае это уже нельзя назвать бизнес-логикой.
А если пользователь скопирует ваши данные в эксель и там будет сортировать — это случайно вашу бизнес-логику не затронет? Фактически мы имеем такой пример, что пользователь получил данные и хочет их смотреть так, как ему хочется. Всякие аналитики это любят очень(не которые «бизнес-», а другие).
Ну в общем ладно. спор пустой. Я просто считаю, что сортировать для удобства пользователя можно даже совершенно не представляя что за данные сортируем(все хорошие гриды это делать умеют). И в таком случае это уже нельзя назвать бизнес-логикой.
А можно поинтерисоваться где вы работаете? В какой компании в считают сортировку исключительно частью бизнес-логики приложения?
Уже давно распространено, что сортировка на сервере не вызывает перезагрузки страницы.
Не всегда есть необходимость посылать AJAX запрос на сервер. Бывают ситуации, когда нужно отстортировать на стороне клиента. Данные уже выбраны из базы, отправлены клиенту. Если он хочет лишь изменить сортировку, то почему не отсортировать без лишних запросов?
А если таблица слишком большая, что разбивается на несколько страниц?
Для этого, конечно, нужно перегружать страницу, либо дергать новый контент с помощью AJAX.
Можно сделать пейджинг таблицы посредством ДЖс или добавить тот же скролл (что бы заголовки таблицы оставались на месте), а дальше всё будет зависть от тонких-клиентов ;)
Однако ajax запрос всё равно требует реквеста и ожидания ответа. Кроме того, ответ нужно ещё обработать. И поэтому он тоже может занимать больше времени чем сортировка на клиенте. Поэтому вопрос остаётся.
Кстати, для фанатов jquery есть такой плагин tablesorter.com/docs/
code.google.com/p/dollar-script/source/browse/branches/jfix/base.js/string.js#23
hello
hello 2
hello 10
hello world
hello
hello 2
hello 10
hello world
НЛО прилетело и опубликовало эту надпись здесь
Смысл этой сортировки? Для сортировки данных в 50? 100? 200 записей? А если записей 1000? Тут мне кажется логичней через ajax подгружать json — передача по времени займет вовсяком случае меньше, чем перезагрузка страницы — но мы хоть получим адекватную сортировку по всем записям в бд.
Запрос к базе может быть «тяжелым». Конечно, применение такой сортировки должно быть оправдано.
Вот вам 1000 строк.
tablesorter.com/docs/example-triggers.html
— вполне приемлемая скорость сортировки.
tablesorter.com/docs/example-triggers.html
— вполне приемлемая скорость сортировки.
Блин. Дело то не в том, на сколько быстро это сортируется. У меня есть 1000000000 записей в бд. Я говорю — хочу отсортировать данные по полю A. Что вы отсортируете своим скриптом? Записи от погруженных данных? Или вы собираетесь загружать все данные, а потом сортировать на стороне клиента?
p.s. Как вы надоели срать в карму. Прежде чем спускать карму — научитесь уважать чужие мнения.
p.s. Как вы надоели срать в карму. Прежде чем спускать карму — научитесь уважать чужие мнения.
Мне кажется, смысл как раз в сортировке таблиц с небольшим количеством данных. В этом случае получается и быстрее и удобнее.
>>> Этот метод очень быстрый
Не верю. Таблица 100 строк, 100 столбцов, думаю браузер надолго задумается.
Существенно оптимизировать можно здесь:
— добавление каждой строки у вас лезет в ДОМ. Это плохо. Лучше push-ем в масив загнать, а потом единожды в ДОМ засунуть.
Не верю. Таблица 100 строк, 100 столбцов, думаю браузер надолго задумается.
Существенно оптимизировать можно здесь:
this.tBody.appendChild(dataCol[i][2]);
— добавление каждой строки у вас лезет в ДОМ. Это плохо. Лучше push-ем в масив загнать, а потом единожды в ДОМ засунуть.
Число столбцов в данном примере не влияет на производительность, т.к. я оперирую строками. Я проверял на 500 и 1000 строках, сортировка идет вполне сносно.
За идею оптимизации спасибо.
За идею оптимизации спасибо.
По поводу незадействованности столбцов не согласен — как не крути при вставке в ДОМ браузер каждую ячейку обрабатывает — а это время.
Я буквально вчера делал сортировку таблиц. При чем очень хитро. :) Задача была в том, чтобы сделать таблицу с 2-мя ФИКСИРОВАННЫМИ столбцами (как в екселе, если столбцов очень много, то прокручиваются все столбцы, кроме первых двух зафиксированных).
Следовательно, пришлось разбить таблицу на 2-е: одна на месте, другую прокручиваем. И, соответственно, «связывать» столбцы, и при сортировке одной таблицы, сортировать другую…
Также, для каждой ячейки есть парсер, так как не все что написано в ячейке нужно сортировать.
ИТОГО: около 100 строк, 20 столцов (что несущественно) — сортировка занимает на моей машине (2.2GHz, 2GB) — около 5-8 секунд!
Я буквально вчера делал сортировку таблиц. При чем очень хитро. :) Задача была в том, чтобы сделать таблицу с 2-мя ФИКСИРОВАННЫМИ столбцами (как в екселе, если столбцов очень много, то прокручиваются все столбцы, кроме первых двух зафиксированных).
Следовательно, пришлось разбить таблицу на 2-е: одна на месте, другую прокручиваем. И, соответственно, «связывать» столбцы, и при сортировке одной таблицы, сортировать другую…
Также, для каждой ячейки есть парсер, так как не все что написано в ячейке нужно сортировать.
ИТОГО: около 100 строк, 20 столцов (что несущественно) — сортировка занимает на моей машине (2.2GHz, 2GB) — около 5-8 секунд!
в случае аякса проблема с ДОМом останется.
Это:
можно оптимизировать вот так:
В этом случае у нас происходит один appendChild и cloneNode для дом узла. Если я не прав поправьте пожалуйста
var l = dataCol.length;
for(var i = 0; i<l; i++) {
this.tBody.appendChild(dataCol[i][2]);
}
можно оптимизировать вот так:
var l = dataCol.length;
var fragment = document.createDocumentFragment();
for (var i = 0; i<l; i++) {
fragment.appendChild(dataCol[i][2]);
}
this.tBody.appendChild(fragment.cloneNode(true));
В этом случае у нас происходит один appendChild и cloneNode для дом узла. Если я не прав поправьте пожалуйста
Я об этом и написал. Просто не равскрывал решение автору, а сказал где и как оптимизировать.
Вы частично правы, что appendChild для tBody происходит один. Но теперь то же самое время уходит на appendChild в fragment.
В IE8 профайлер показывает 234мс в обоих случаях.
Кардинально проблему это не решает.
В IE8 профайлер показывает 234мс в обоих случаях.
Кардинально проблему это не решает.
А на каком количестве строк вы тестировали?
Скорее всего выигрыш будет, при увеличении числа строк до 1000…
И посмотрите в ие6, разницу вы заметите…
DocumentFragment — является облегченным контейнером для DOM-узлов.
appendChild для tBody != appendChild для fragment
одно дело когда происходит обращение каждый раз к дом модели, другое к памяти…
Так же можно использовать другой вариант:
this.tBody.innerHTML = html.join("");
где html это строковый элементов массив
Скорее всего выигрыш будет, при увеличении числа строк до 1000…
И посмотрите в ие6, разницу вы заметите…
DocumentFragment — является облегченным контейнером для DOM-узлов.
appendChild для tBody != appendChild для fragment
одно дело когда происходит обращение каждый раз к дом модели, другое к памяти…
Так же можно использовать другой вариант:
this.tBody.innerHTML = html.join("");
где html это строковый элементов массив
Тестировал на 500 строках.
Ноды строк находятся в документе, при вызове fragment.appendChild(dataCol[i][2]) ноды перемещаются в fragment, т.е.
обращение к DOM всеравно происходит.
С innerHTML может получиться быстрее, но я не уверен что будет значительно. И еще придется делать костыль для IE, т.к. у него innerHTML для table и tbody только для чтения.
Ноды строк находятся в документе, при вызове fragment.appendChild(dataCol[i][2]) ноды перемещаются в fragment, т.е.
обращение к DOM всеравно происходит.
С innerHTML может получиться быстрее, но я не уверен что будет значительно. И еще придется делать костыль для IE, т.к. у него innerHTML для table и tbody только для чтения.
Сортировка 10 записей может быть реализована любым алгоритмом — даже самым неоптимальным. Было бы гораздо лучше, если бы Вы выложили пример Вашей сортировки для 4000 записей.
Когда-то давным давно у меня стояла задача сортировки данных у клиента. Я нашёл несколько скриптов, но все они были медленными, кроме одного единственного, который я и применил. Поэтому, хотелось бы оценить этот скрипт на больших объёмах данных. В противном случае, чем этот алгоритм сортировки отличается от десятков уже кем-то написанных?
Когда-то давным давно у меня стояла задача сортировки данных у клиента. Я нашёл несколько скриптов, но все они были медленными, кроме одного единственного, который я и применил. Поэтому, хотелось бы оценить этот скрипт на больших объёмах данных. В противном случае, чем этот алгоритм сортировки отличается от десятков уже кем-то написанных?
Обычно табличную информацию выводят с разбивкой на страницы, а сортировка должна сортировать данные по всем страницам. Поэтому метод на реальных задачах не применим, разве что вы загрузите всю таблицу в какой-то локальный кэш и в дальнейшем будете работать только с ним, но даже тогда передача всей таблицы из БД может перекрыть выгоду от локальной сортироки.
Плюс к этому память, выделяемая на сервере для выборки всех записей может неожиданно закончиться, когда объём данных перевалит за пару тысяч значений.
А если бить выборку из базы по страницам, то это ничем не отличается от запросов к серверу с выборкой ограниченного объёма.
Скорее всего, сортировка на клиенте нужна в небольших таблицах. В больших — обращение к серверу, на котором выборки кэшируются.
А если бить выборку из базы по страницам, то это ничем не отличается от запросов к серверу с выборкой ограниченного объёма.
Скорее всего, сортировка на клиенте нужна в небольших таблицах. В больших — обращение к серверу, на котором выборки кэшируются.
НЛО прилетело и опубликовало эту надпись здесь
Большое спасибо! Давно искал простые способы реализации. И очень понятный пример.
Я не понимаю, к чему придирки некоторых комментаторов? Пример хороший, наглядный. С возможностью доработки прямыми ручками. То, что он не универсален никак не умоляет его достоинств.
Главное здесь — идея и реализация. Автор поделился, а те, кому это интересно — взяли на заметку.
Имеющие более другие варианты — пишите, статей много не бывает.
Я не понимаю, к чему придирки некоторых комментаторов? Пример хороший, наглядный. С возможностью доработки прямыми ручками. То, что он не универсален никак не умоляет его достоинств.
Главное здесь — идея и реализация. Автор поделился, а те, кому это интересно — взяли на заметку.
Имеющие более другие варианты — пишите, статей много не бывает.
К минусам клиентского варианта также относится невозможность работы с большими массивами данных.
Приведенный в статье минус серверного варианта решается использованием асинхронного javascript
Приведенный в статье минус серверного варианта решается использованием асинхронного javascript
Если кому интересно, вот парочка реализаций сортировки таблиц на Javascript
unobtrusive-table-sort
able Sorting, Filtering, Etc
Работают достаточно быстро и есть интересные фичи.
unobtrusive-table-sort
able Sorting, Filtering, Etc
Работают достаточно быстро и есть интересные фичи.
Обычно таки в реальных проектах таблицы многостраничные, то есть в данный момент на экране только часть данных.
Но все равно — вполне достойное решение со своей областью применимости.
Но все равно — вполне достойное решение со своей областью применимости.
Вполне хорошее решение. Критики этой статьи, в своих ответах утверждают, что сортировку лучше делать на сервере. Пожалуй они правы для веба, но есть еще и десктопные приложения сделанные на технологии AIR, и для них вполне отличное решение. :)
Спасибо.
Спасибо.
Невероятно мощный и надежный плагин jQuery для сортировки таблиц — http://www.datatables.net пользуюсь активно и продолжительно, лучше еще не видел. Настраивается буквально все, документация на уровне, активно развивается.
улыбнуло
P.S. на тему быстродействия можно почитать блог YASS — habrahabr.ru/blogs/yass/
при сортировке ноды таблицы переставляются только в конце посредством последовательного вызова appendChild.А известно ли Вам, уважаемый автор, что каждое обращение к DOM настолько ресурсоемко, что даже вместо 10 элементарных изменений лучше сделать 1 комплексное? И еще мне кажется, что while(i--) вкупе с внутренним сравнением будет побыстрее сортировки массива таким способом. Если у кого будет время на написание тестов и сравнение браузеров, буду весьма признателен.
P.S. на тему быстродействия можно почитать блог YASS — habrahabr.ru/blogs/yass/
Про скорость работы с DOM я в курсе.
На данный момент 100 строк переставляется за 100 вызовов appendChild. Скажите пожалуйста, как существующие ноды строк Вы предлагаете комплексно переставить согласно порядку в массиве, чтобы число операций с DOM был существенно ниже?
На данный момент 100 строк переставляется за 100 вызовов appendChild. Скажите пожалуйста, как существующие ноды строк Вы предлагаете комплексно переставить согласно порядку в массиве, чтобы число операций с DOM был существенно ниже?
очевидно же: полностью переписав исходный элемент. Если мы будем содержать подготовленный JS-массив, который будет включать все данные из таблицы. А на основе этого массива будет строить саму таблицу динамически — дело намного быстрее пойдет.
в смысле? У нас есть таблица на странице, мы ее сортируем. Какая разница конечному пользователю, что у нас там на странице еще напихано?
А про «удовлетворительно — неудовлетворительно» писать не стоит, если у Вас топик направлен на решение как раз проблемы быстродействия. Т.е. тут Вы сами себе немного противоречите, когда сначала заявляете, что «данное решение самое быстрое», а потом «но скорость его работы удовлетворительная».
А про «удовлетворительно — неудовлетворительно» писать не стоит, если у Вас топик направлен на решение как раз проблемы быстродействия. Т.е. тут Вы сами себе немного противоречите, когда сначала заявляете, что «данное решение самое быстрое», а потом «но скорость его работы удовлетворительная».
Хорошо, спрошу иначе.
Есть дерево DOM. В нем есть 100 нод. Как изменить порядок этих нод относительно друг друга используя много меньше 100 операций с нодами?
Есть дерево DOM. В нем есть 100 нод. Как изменить порядок этих нод относительно друг друга используя много меньше 100 операций с нодами?
если предполагается, что у нас нет никакого массива в JS, то предложенный метод «вставочной» сортировки — самый быстрый. Но в условиях, что DOM-операции крайне дорого обходятся, его применении стоит под большим вопросом (DOM вообще использовать не стоит).
Да, я согласен. Всему есть свое применение. Поэтому я считаю, что метод, описанный мной имеет место быть в некоторых ситуациях. Внедрение будет «малокровным» и для сравнительно небольших таблиц — самое оно.
Сортировать js можно только если таблица умещается полностью на 1 странице.
Это было почти верно до появления новых версий браузеров. Сейчас Javascript очень сильно ускорился, и сортировка работает достаточно быстро. Таблица 1500 x 15 сортируется за одну — две секунды, причём это алгоритм трёхлетней давности.
Да, но получается, что ее всю сначала нужно загрузить в тело страницы… хотя сейчас и инет быстрый :).
если грузить таблицы в JSON формате, да ещё паковать gzip' ом — очень быстро получается.
Статью я бы назвал как-нибудь вроде «Учимся применять функцию Array.sort в javascript», а не более претензионное «Быстрая сортировка таблиц посредством Javascript» (которая больше подходит, если бы вы здесь дествительно расписали какой-то новый алгоритм сортировки на javascript).
Далее, Array.reverse для обращения результатов сортировки это… это как минимум мне не понятно.
Что мешает сделать как обычно?
function MySort (items, sortDirection)
{
if (!items)
return;
var sort_direction_multiplier = sortDirection? 1: -1;
items = items.sort(function(a, b)
{
if (a > b)
return sort_direction_multiplier;
else if (a < b)
return -sort_direction_multiplier;
return 0;
});
return items;
}
(может где в синтаксисе напутал — но суть понятна)
На счёт сторонников сортировки на сервере — это не всегда оправданно. Если таблица заведомо не сильно большая, то можно выдать клиенту все данные (к примеру, через тот же Ajax и gzip) и дать инструменты для работы (сортировка/фильтрация) прямо на клиенте. Для клиента это будет гораздо приятнее. Правда это уже всё мелочи и дело вкуса разработчика, по большому счёту.
На счёт тех, кто говорил, что если запрос очень сложный — в этих случаях сначала выбираются id-шники а уж потом с ними работают (разбивают на странице и при выборке не забывают, что нужно сохранять порядок следования результатов согласно порядку переданных id-шников).
Далее, Array.reverse для обращения результатов сортировки это… это как минимум мне не понятно.
Что мешает сделать как обычно?
function MySort (items, sortDirection)
{
if (!items)
return;
var sort_direction_multiplier = sortDirection? 1: -1;
items = items.sort(function(a, b)
{
if (a > b)
return sort_direction_multiplier;
else if (a < b)
return -sort_direction_multiplier;
return 0;
});
return items;
}
(может где в синтаксисе напутал — но суть понятна)
На счёт сторонников сортировки на сервере — это не всегда оправданно. Если таблица заведомо не сильно большая, то можно выдать клиенту все данные (к примеру, через тот же Ajax и gzip) и дать инструменты для работы (сортировка/фильтрация) прямо на клиенте. Для клиента это будет гораздо приятнее. Правда это уже всё мелочи и дело вкуса разработчика, по большому счёту.
На счёт тех, кто говорил, что если запрос очень сложный — в этих случаях сначала выбираются id-шники а уж потом с ними работают (разбивают на странице и при выборке не забывают, что нужно сохранять порядок следования результатов согласно порядку переданных id-шников).
фигасе оптимизированная версия! Firefox завис блин.
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Быстрая сортировка таблиц посредством Javascript