Построение динамических форм¶
28.02.2022
Многие формы, например, анкеты, могут быть очень похожи друг на друга по формату и замыслу. Чтобы быстрее и проще генерировать различные версии таких форм, можно создать динамический шаблон формы на основе метаданных, описывающих модель бизнес-объектов.
Затем использовать шаблон для автоматической генерации новых форм в соответствии с изменениями в модели данных.
Эта техника особенно полезна, когда у вас есть тип формы, содержание которой должно часто меняться, чтобы соответствовать быстро меняющимся требованиям бизнеса и нормативных актов. Типичным примером является анкета.
Вам может понадобиться получить данные от пользователей в различных контекстах.
Формат и стиль форм, которые видит пользователь, должны оставаться постоянными, в то время как фактические вопросы, которые необходимо задать, зависят от контекста.
В этом уроке вы создадите динамическую форму, представляющую собой базовую анкету. Вы создаете онлайн-приложение для героев, ищущих работу.
Агентство постоянно вносит изменения в процесс заполнения анкеты, но с помощью динамической формы
вы можете создавать новые формы "на лету", не изменяя код приложения.
Учебное пособие проведет вас через следующие шаги.
- Включите реактивные формы для проекта.
- Создайте модель данных для представления элементов управления формы.
- Наполните модель данными образца.
- Разработайте компонент для динамического создания элементов управления формы.
Созданная вами форма использует валидацию ввода и стилизацию для улучшения пользовательского опыта. В ней есть кнопка "Отправить", которая активируется только в том случае, если все введенные пользователем данные достоверны, а недопустимые данные отмечаются цветовой маркировкой и сообщениями об ошибках.
Базовая версия может развиваться, чтобы поддерживать более богатое разнообразие вопросов, более изящный рендеринг и улучшать пользовательский опыт.
См. пример.
Предварительные условия¶
Перед выполнением этого руководства вы должны иметь базовое представление о следующем.
- TypeScript и программирование на HTML5
- Фундаментальные концепции Angular app design
- Базовые знания реактивных форм
Включите реактивные формы для вашего проекта¶
Динамические формы основаны на реактивных формах. Чтобы предоставить приложению доступ к директивам реактивных форм, корневой модуль импортирует ReactiveFormsModule
из библиотеки @angular/forms
.
Следующий код из примера показывает настройку в корневом модуле.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 |
|
Создание объектной модели формы¶
Динамическая форма требует объектной модели, которая может описать все сценарии, необходимые для функциональности формы. Пример формы hero-application представляет собой набор вопросов — то есть каждый элемент управления в форме должен задавать вопрос и принимать ответ.
Модель данных для этого типа формы должна представлять вопрос. Пример включает DynamicFormQuestionComponent
, который определяет вопрос как основной объект в модели.
Следующий QuestionBase
является базовым классом для набора элементов управления, которые могут представлять вопрос и ответ на него в форме.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
Определите классы управления¶
Из этой базы пример выводит два новых класса, TextboxQuestion
и DropdownQuestion
, которые представляют различные типы элементов управления. Когда вы создаете шаблон формы на следующем этапе, вы инстанцируете эти конкретные типы вопросов, чтобы динамически отобразить соответствующие элементы управления.
Тип элемента управления TextboxQuestion
.
Представляет вопрос и позволяет пользователям вводить данные.
1 2 3 4 5 |
|
Тип управления TextboxQuestion
представлен в шаблоне формы с помощью элемента <input>
. Атрибут type
элемента определяется на основе поля type
, указанного в аргументе options
(например, text
, email
, url
).
Тип элемента управления DropdownQuestion
.
Представляет список вариантов выбора в поле выбора.
1 2 3 4 5 |
|
Составление групп форм¶
Динамическая форма использует сервис для создания сгруппированных наборов элементов управления вводом на основе модели формы. Следующий QuestionControlService
собирает набор экземпляров FormGroup
, которые потребляют метаданные из модели вопроса. Вы можете указать значения по умолчанию и правила проверки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
Составление содержимого динамической формы¶
Сама динамическая форма представлена компонентом-контейнером, который вы добавите на следующем этапе. Каждый вопрос представлен в шаблоне компонента формы тегом <app-question>
, который соответствует экземпляру DynamicFormQuestionComponent
.
Компонент DynamicFormQuestionComponent
отвечает за отображение деталей отдельного вопроса на основе значений в связанном с данными объекте вопроса. Форма полагается на директиву [formGroup]
для соединения HTML шаблона с базовыми объектами управления.
Компонент DynamicFormQuestionComponent
создает группы форм и заполняет их элементами управления, определенными в модели вопроса, задавая правила отображения и проверки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Цель DynamicFormQuestionComponent
— представить типы вопросов, определенные в вашей модели. На данный момент у вас есть только два типа вопросов, но вы можете придумать гораздо больше. Оператор ngSwitch
в шаблоне определяет, какой тип вопроса отображать.
Переключатель использует директивы с селекторами formControlName
и formGroup
.
Обе директивы определены в ReactiveFormsModule
.
Предоставление данных¶
Еще один сервис необходим для предоставления определенного набора вопросов, из которых можно построить индивидуальную форму. В этом упражнении вы создадите QuestionService
, который будет предоставлять массив вопросов из жестко закодированных данных образца.
В реальном приложении сервис может получать данные из внутренней системы.
Ключевым моментом, однако, является то, что вы полностью контролируете вопросы героя анкеты через объекты, возвращаемые из QuestionService
.
Чтобы поддерживать анкету по мере изменения требований, вам нужно только добавлять, обновлять и удалять объекты из массива questions
.
Сервис QuestionService
предоставляет набор вопросов в виде массива, связанного с @Input()
вопросами.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
|
Создание шаблона динамической формы¶
Компонент DynamicFormComponent
является точкой входа и основным контейнером для формы, которая представлена с помощью <app-dynamic-form>
в шаблоне.
Компонент DynamicFormComponent
представляет список вопросов, связывая каждый из них с элементом <app-question>
, который соответствует DynamicFormQuestionComponent
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
Отображение формы¶
Для отображения экземпляра динамической формы шаблон оболочки AppComponent
передает массив questions
, возвращаемый QuestionService
, компоненту-контейнеру формы, <app-dynamic-form>
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
Пример предоставляет модель приложения для работы с героями, но в нем нет ссылок на какой-либо конкретный вопрос героя, кроме объектов, возвращаемых QuestionService
. Такое разделение модели и данных позволяет вам перепрофилировать компоненты для любого типа опросов, если они совместимы с объектной моделью question.
Обеспечение достоверности данных¶
Шаблон формы использует динамическое связывание метаданных для отображения формы, не делая никаких жестких предположений о конкретных вопросах. Он добавляет метаданные элементов управления и критерии проверки динамически.
Для обеспечения корректного ввода данных кнопка Сохранить отключена до тех пор, пока форма не перейдет в корректное состояние. Когда форма становится валидной, нажмите кнопку Сохранить, и приложение отобразит текущие значения формы в виде JSON.
На следующем рисунке показана окончательная форма.
Следующие шаги¶
Различные типы форм и коллекция элементов управления.
В этом уроке показано, как создать анкету, которая является одним из видов динамических форм. В примере используется FormGroup
для сбора набора элементов управления. Пример динамической формы другого типа см. в разделе Создание динамических форм в руководстве Reactive Forms. В том примере также показано, как использовать FormArray
вместо FormGroup
для сбора набора элементов управления.
Валидация пользовательского ввода
Раздел Проверка ввода формы знакомит с основами работы проверки ввода в реактивных формах.
В руководстве Form validation guide эта тема рассматривается более подробно.