Русский
Русский
English
Статистика
Реклама

Стандартизируем поведение форм в проекте (Angular)


Чтобы создать дружелюбный интерфейс, необходимо обеспечить однообразное поведение всех форм в приложении. Однообразное поведение часто достигается повторяющимся кодом, хоть и в неявной форме. Позвольте поделиться наброском паттерна, который, по моему мнению, упрощает разработку и стандартизирует поведение форм.

Если код отправки форм в вашем проекте похож на этот, советую заглянуть под кат.

onSubmit(): void
// login.component.ts// bad practicesonSubmit(): void {  this.formSubmitted = true;  this.isUnhandledServerError = false;  if (!this.formGroup.valid) return;  this.isLoading = true;  const { username, password } = this.formGroup.value;  this.login(username, password)    .pipe(finalize(() => (this.isLoading = false)))    .subscribe({ error: error => this.handleError(error) });}


Для тех, кто просто любит код:
Проект на stackblitz до рефакторинга.
Проект на stackblitz после рефакторинга.

Описание проблемы


Формы требуют учитывать много нюансов. С функциональной точки зрения, форма всего лишь отправляет введенную пользователем информацию на сервер. Но для обеспечения качественного UX помимо всего приходится заниматься валидацией, отображать ошибки от сервера, индикатор загрузки, и т.п. Эти детали на практике часто остаются без должного внимания со стороны разработчиков, что либо негативно сказывается на комфорте использования приложения, либо выливается в дублирование кода и превращает разработку форм в невыносимую рутину.

Предлагаю разобрать пример обработчика отправки формы, хорошего с точки зрения UX, но плохого с точки зрения разработки. Проект на stackblitz до рефакторинга.

// login.component.tsonSubmit(): void {  this.formSubmitted = true; // подкрашиваем невалидные элементы  this.isUnhandledServerError = false; // скрываем сообщение об неизвестной ошибке на сервере  if (!this.formGroup.valid) return; // валидируем форму  this.isLoading = true; // показываем индикатор загрузки  const { username, password } = this.formGroup.value;  this.login(username, password) // отправляем данные на сервер    .pipe(finalize(() => (this.isLoading = false))) // скрываем индикатор загрузки    .subscribe({ error: error => this.handleError(error) });}

Как вы видите, в данном обработчике учтено большое количество деталей, составляющих UX. Проблема лишь в том, что при таком подходе, эти нюансы придется прописывать для каждой формы в приложении.

Решение


Чтобы упростить разработку и стандартизировать поведение форм в приложении, необходимо вынести код обработчика отправки формы в отдельный класс. Проект на stackblitz после рефакторинга. (Я намеренно упростил код для примера, в реальном проекте нужно заменить все boolean поля на Observable.)

class Form<T> {    submitted = false;    pending = false;    hasUnhandledServerError = false;    constructor(private formGroup: FormGroup, private action: (value: any) => Observable<T>) {}    submit(): Observable<T> {        if (this.pending) return EMPTY;        this.submitted = true;        this.hasUnhandledServerError = false;        if (this.formGroup.valid) {            this.pending = true;            return this.action(this.formGroup.value).pipe(                tap({ error: () => (this.hasUnhandledServerError = true) }),                finalize(() => (this.pending = false)),            );        }        return EMPTY;    }}

Таким образом, мы концентрируем большую часть особенностей UX в одном классе и избавляемся от дублирования логики. Теперь написание новой формы будет отнимать меньше времени, а дополнить поведение форм во всем приложении можно через изменение одного лишь класса Form.

Почему не вынести это в библиотеку?


Требования к UX для каждого проекта уникальны, и в большей степени зависят от дизайнера. Мне уже приходилось переопределять поведение стандартных Material элементов по пожеланию заказчика. Поэтому я не вижу хоть сколько-нибудь возможным стандартизировать поведение форм во всех приложениях с помощью одной библиотеки. Пусть поведение интерфейса остается во власти дизайнера и разработчиков. Тем не менее я считаю, что это неплохая идея выделять связанную с UX логику в отдельные классы.

Надеюсь, пример был полезен, и вы попробуете использовать идею в своих проектах. Пока!
Источник: habr.com
К списку статей
Опубликовано: 18.11.2020 12:16:11
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Разработка веб-сайтов

Проектирование и рефакторинг

Angular

Ux

Формы

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru