Фильтрация и сортировка данных #
Проблема отображения большого объёма данных #
В рамках данной работы рассмотрим типичные сценарии работы с большими наборами данных. Ключевая особенность заключается в том, что невозможно предоставлять пользователю сразу большой набор данных:
- Большой объём данных долго обрабатывает система (как на сервере, так и на клиенте), что делает работу пользователя с системой неудобной.
- Пользователю неудобно работать с очень большими документами.
- Системы хотят самостоятельно обрабатывать свои данные и не делиться этими данными с другими системами.
Для быстрого предоставления данных применяется подход с частичным отображением информации, постраничный вывод. Для решения проблемы нахождения информации реализуется фильтрация элементов по различным критериям.
HTML-формы #
Для обеспечения передачи данных от пользователя к веб-приложению используются интерактивные элементы, формы. Каждая форма состоит из нескольких полей, в которые пользователь может вводить данные, выбирать элементы из списка и т.д.
Формы описываются с помощью HTML-элемента form, который включает в себя ряд элементов input, textarea, button, описывающие конкретные поля ввода и интерактивные элемента. В рамках одного HTML-документа может находится несколько форм, предлагающие пользователю выполнить разные действия.
Для указания URI-адреса, который должен обработать данные, переданные с формы, используется атрибут action элемента form. По умолчанию данный адрес совпадает с адресом самого HTML-документа. Для большинства форм данное поведение является удобным и дополнительно определять путь не нужно.
Формы могут посылать GET и POST-запросы. Для указания HTTP-метода, который будет послан, используется атрибут method. По умолчанию форма будет отправлять GET-запрос. Это поведение необходимо использовать в данной практической работе.
При использовании GET-запросов данные с формы передаются в формате параметров, записанных в строку запроса. Названием параметра зачастую выступает название поля ввода, а значением — данные, которые указал или не указал пользователь.
Вы можете посмотреть на примеры форм на следующих страницах:
Сценарий фильтрации, сортировки #
В рамках данного сценария разработчику необходимо предоставить пользователю интерактивные элементы для ввода данных рядом с отображаемым списком элементов. Решение задач фильтрации и сортировки не должно изменять внутреннее состояние приложения, а влиять только на выводимые пользователю данные. Таким образом для отправки данных веб-приложению необходимо использовать GET-запросы.
Рассмотрим принципиальную последовательность действий, которые позволят пользователю выполнить фильтрацию или сортировку отображаемых данных:
sequenceDiagram
autonumber
actor user as Пользователь
participant brow as Браузер
participant serv as Сервер
user ->> brow : Открывает ссылку
на документ со списком
brow ->> serv : Выполняет GET-запрос
документа по ссылке
serv ->> brow : HTML-документ
с данными и формой
brow ->> user : Отображает полученный документ
user ->> brow : Пользователь заполняет
поля формы и нажимает
кнопку «Применить»
brow ->> serv : Посылает GET-запрос
с параметрами формы
serv ->> brow : HTML-документ с данными
и заполненной формой
brow ->> user : Отображает документ
с нужной страницей
Ключевые особенности подхода:
- Для указания параметров фильтрации используются HTML-формы, интерактивные элементы.
- Данные с формы передаётся на сервер с помощью GET-запроса, а не POST-запроса.
- Данные с формы не должны «пропадать» после передачи их пользователю. Т.е. если пользователь указал какие-то параметры внутри формы, то они снова должны быть показаны пользователю.
- Пользователь может скопировать ссылку и поделиться ей с другими пользователями, чтобы они увидели такой же результат фильтрации.
- Пользователь может открыть несколько вкладок с одним сайтом и применить разные параметры фильтрации и сортировки для отображения одних и тех же данных.
Данные с формы передаются в качестве параметров маршрута: https://some.dev/list?owner=maria&version=15
Взаимодействие с постраничным выводом #
Оба подхода по фильтрации и по постраничному выводу используют одинаковый способ передачи данных от пользователя — параметры URI. Необходимо сохранять параметры фильтрации при переходе между различными страницами в выдаче отфильтрованного списка. В тоже время при изменении параметров фильтрации не стоит сохранять порядковый номер отображаемой страницы с данными.
Таким образом при формировании ссылок на другие страницы выдачи следует управлять только лишь параметром, указывающим на номер отображаемой страницы. В нашем случае им выступает параметр page
. Другие же параметры не должны изменяться.
Класс Uri предоставляет необходимые возможности по изменению только целевого параметра.
Получение параметров запроса #
Обработка параметров, пришедших с формы, не отличается от обработки параметров, которые присылаются для реализации постраничного вывода.
Проблема нумерации элементов #
При использовании следующих подходов невозможно использовать метод withIndex
для получения уникального номера элемента:
- фильтрации;
- частичной выборки;
- сортировки.
Вместо этого необходимо:
- Добавить порядковый или уникальный номер внутрь элемента списка.
- При создании элемента необходимо использовать очередной номер из счётчика.
- Счётчик необходимо расположить внутри класса-списка.
Методы, возвращающие выборки данных, должны возвращать просто список из элементов. Элементы уже самостоятельно смогут сообщить свой уникальный индекс в рамках коллекции.
Задача № 1. Реализация фильтрации списка треугольников #
Реализуйте фильтрацию списка добавленных треугольников по следующим критериям:
- Минимальная длина наименьшей стороны треугольника.
- Максимальная длина наибольшей стороны треугольника.
При отсутствии значения аргумента данный фильтр применяться не должен.
Поход к реализации:
- Реализуйте отображение формы на странице со списком документов.
- С помощью шаблона формы из Bootstrap добавьте на страницу вывода списка треугольников форму, состоящую из двух полей ввода и кнопки для отправки данных.
- Для каждого поля ввода укажите его уникальное имя (атрибут name), а также определитесь с типом компонента (атрибут type) , который наиболее точно позволит пользователю ввести корректные данные.
- Убедитесь, что данные, которые пользователь ввёл в форму, передаются обработчику HTTP-запроса в формате параметров запроса. Самый простой способ — заполнить поля формы и отправить её веб-приложению. Поля формы должны передаться с помощью параметров HTTP-запроса.
- Отобразите параметры, которые ввёл пользователь на HTML-документе. Это необходимо, чтобы пользователь смог исправить свой некорректный ввод.
- Модифицируйте модель (класс ViewModel) так, чтобы она хранила в себе параметры, которые пользователь указал с помощью формы. Данные параметры будет удобно описать как строковые типы, способные принимать
null
-значения, т.к. пользователь может не передать их или передать их в неправильном формате. - Модифицируйте шаблон HTML-документа таким образом, чтобы он использовал передаваемые через модель данные. Атрибут value полей ввода позволяет установить изначальное значение.
- Обработайте параметры запроса в HTTP-обработчике и передайте их модели, чтобы их можно было отобразить пользователю в HTML-документе.
- Модифицируйте модель (класс ViewModel) так, чтобы она хранила в себе параметры, которые пользователь указал с помощью формы. Данные параметры будет удобно описать как строковые типы, способные принимать
- Отфильтруйте данные, отображаемые пользователю.
- По возможности преобразуйте данные, которые передал пользователь, из строкового значения в вещественные числа. В рамках данной практической считаем, что пользователь введёт данные в корректном формате. В случае ошибочного значения просто преобразуйте строку к
null
-значению. Это будет совпадать с ситуацией, когда пользователь ничего не указал в поле ввода. - Сформируйте метод у класса
Triangles
, возвращающий список отфильтрованных треугольников согласно данным, приходящим от пользователя. Данный метод должен принимать в качестве аргументов 2 вещественных числа, способных приниматьnull
-значения. При наличии значения и у каждого из параметров, он должен учитываться при фильтрации элементов. - Используйте данный метод для формирования списка данных для отображения пользователю.
- По возможности преобразуйте данные, которые передал пользователь, из строкового значения в вещественные числа. В рамках данной практической считаем, что пользователь введёт данные в корректном формате. В случае ошибочного значения просто преобразуйте строку к
Задача № 2. Поддержка фильтрации и постраничного вывода #
Модифицируйте приложение таким образом, чтобы при переходе между страницами, сохранялись и применялись параметры фильтрации.
Задача № 3. Реализация сортировки #
К форме фильтрации данных добавьте ещё 1 поле, с помощью которого пользователь может управлять сортировкой данных в списке. Данное поле должно содержать следующие варианты сортировки:
- По порядку добавления с увеличением номера.
- По порядку добавления с уменьшением номера.
- Сначала самые большие по площади.
- Сначала самые маленькие по площади.
- Сначала самые большие по периметру.
- Сначала самые маленькие по периметру.
Для кодирования возможных вариантов рекомендуется использовать классы-перечисления.