Поиск по сайту:

Как использовать реактивные формы в Angular


Введение

Angular предоставляет два способа работы с формами: формы на основе шаблона и реактивные формы (также известные как формы на основе модели). Формы на основе шаблонов — это способ работы с формами в Angular по умолчанию. В формах, управляемых шаблонами, директивы шаблона используются для построения внутреннего представления формы. С реактивными формами вы создаете собственное представление формы в классе компонента.

Примечание. Реактивные формы были представлены в Angular 2.

Вот некоторые из преимуществ реактивных форм:

  • Использование пользовательских валидаторов
  • Динамическое изменение проверки
  • Динамическое добавление полей формы

В этой статье вы узнаете, как можно применить реактивные формы к примеру приложения Angular.

Предпосылки

Если вы хотите следовать этой статье, вам понадобятся:

  • Node.js установлен локально, что можно сделать, следуя инструкциям по установке Node.js и созданию локальной среды разработки.

Этот пост предполагает, что у вас есть базовые знания Angular.

В этом посте также предполагается, что вы строите новый проект Angular, сгенерированный @angular/cli. Вы можете обратиться к этому сообщению, если начинаете работу с Angular CLI.

Это руководство было проверено с помощью Node v15.1.0, npm v6.14.8, @angular/core v11.0.0 и @angular/forms v11. .0.0.

Шаг 1 — Настройка проекта

Для целей этого руководства вы создадите проект Angular по умолчанию, сгенерированный с помощью @angular/cli.

  1. npx @angular/cli new angular-reactive-forms-example --style=css --routing=false --skip-tests

Это настроит новый проект Angular со стилями, установленными на «CSS» (в отличие от «Sass», «Less» или «Stylus»), без маршрутизации и пропуска тестов.

Перейдите в только что созданный каталог проекта:

  1. cd angular-reactive-forms-example

Для работы с реактивными формами вы будете использовать ReactiveFormsModule вместо FormsModule.

Откройте app.module.ts в редакторе кода и добавьте ReactiveFormsModule:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

На этом этапе у вас должен быть новый проект Angular с ReactiveFormsModule.

Шаг 2 — Добавление формы в шаблон компонента

В реактивных формах логика полностью объявляется в классе компонента.

Откройте app.component.html в редакторе кода и добавьте следующие строки кода:

<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)">
  <div>
    <label>
      Name:
      <input formControlName="name" placeholder="Your name">
    </label>
  </div>
  <div>
    <label>
      Email:
      <input formControlName="email" placeholder="Your email">
    </label>
  </div>
  <div>
    <label>
      Message:
      <input formControlName="message" placeholder="Your message">
    </label>
  </div>
  <button type="submit">Send</button>
</form>

Этот код создаст форму с тремя полями: name, email и message. Также будет кнопка отправить с надписью Отправить. При отправке формы будет вызываться метод onSubmit(myForm).

Примечание. Если вы используете Angular 2.x, вам также следует добавить директиву novalidate с открывающим тегом form, так как Angular переопределяет проверку HTML5. В Angular 4+ novalidate автоматически добавляется за кулисами.

Давайте разберем это:

  • formGroup: форма будет рассматриваться как FormGroup в классе компонента, поэтому директива formGroup позволяет дать имя сформировать группу.
  • ngSubmit: это событие, которое будет запущено при отправке формы.
  • formControlName: каждое поле формы должно иметь директиву formControlName со значением, которое будет именем, используемым в классе компонента.

На этом этапе у вас должен быть новый проект Angular с шаблоном компонента, который использует форму.

Шаг 3 — Создание класса компонента

Затем в классе компонента вы определите FormGroup и отдельные элементы FormControl внутри FormGroup.

Если при новом элементе FormControl указано значение, оно будет использоваться в качестве начального значения для поля.

Обратите внимание, что имена FormGroup и FormControl совпадают с теми, что использовались в шаблоне. Также обратите внимание на то, как вы инициализируете FormGroup в хуке жизненного цикла ngOnInit:

import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;

  ngOnInit() {
    this.myForm = new FormGroup({
      name: new FormControl('Sammy'),
      email: new FormControl(''),
      message: new FormControl('')
    });
  }

  onSubmit(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Name', form.value.name);
    console.log('Email', form.value.email);
    console.log('Message', form.value.message);
  }
}

Для целей этого руководства метод onSubmit фактически не передает отправленные значения формы какой-либо внешней службе или серверу. Он служит для демонстрации того, как вы можете получить доступ к допустимости формы и значениям FormControl.

На этом этапе вы можете скомпилировать свое приложение и открыть его в веб-браузере. После ввода значений для name, email и message и нажатия кнопки «Отправить» журнал консоли отобразит значения.

Шаг 4 — Обновление класса компонентов для использования FormBuilder

Конструкцию формы ngOnInit можно переписать с помощью помощника FormBuilder. Это позволяет отказаться от всех обновлений групп форм и элементов управления формами.

Снова откройте app.component.ts в редакторе кода и удалите FormControl и замените FormGroup на FormBuilder:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.myForm = this.fb.group({
      name: 'Sammy',
      email: '',
      message: ''
    });
  }

  onSubmit(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Name', form.value.name);
    console.log('Email', form.value.email);
    console.log('Message', form.value.message);
  }
}

Этот код с FormBuilder уменьшает объем шаблонного кода для создания FormGroup.

Шаг 5 — Обновление класса компонентов для использования валидаторов

Добавьте класс Validators в свой импорт и объявите элементы управления формы с помощью массивов вместо простых строковых значений.

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

Повторно посетите app.component.ts в редакторе кода и добавьте Validators:

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.myForm = this.fb.group({
      name: ['Sammy', Validators.required],
      email: ['', [Validators.required, Validators.email]],
      message: ['', [Validators.required, Validators.minLength(15)]],
    });
  }

  onSubmit(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Name', form.value.name);
    console.log('Email', form.value.email);
    console.log('Message', form.value.message);
  }
}

Этот код добавляет required в поля name, email и message. Это также гарантирует, что значение email использует формат действительного адреса электронной почты. Это также гарантирует, что значение message имеет длину не менее 15 символов.

Если какое-либо из этих требований к форме не выполняется, значение valid будет false. Если все эти требования формы выполнены, значение valid будет true.

Шаг 6 — Доступ к значению формы и валидности в шаблоне

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

Перейдите на app.component.html и используйте *ngIf, чтобы отобразить сообщения обратной связи для пользователя, если значения формы недействительны:

<form [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)">
  <div>
    <label>
      Name:
      <input formControlName="name" placeholder="Your name">
    </label>
    <div *ngIf="myForm.get('name').invalid && (myForm.get('name').dirty || myForm.get('name').touched)">
      Please provide a name.
    </div>
  </div>
  <div>
    <label>
      Email:
      <input formControlName="email" placeholder="Your email">
    </label>
    <div *ngIf="myForm.get('email').invalid && (myForm.get('email').dirty || myForm.get('email').touched)">
      Please provide a valid email address.
    </div>
  </div>
  <div>
    <label>
      Message:
      <input formControlName="message" placeholder="Your message">
    </label>
    <div *ngIf="myForm.get('message').invalid && (myForm.get('message').dirty || myForm.get('message').touched)">
      Messages must be at least 15 characters long.
    </div>
  </div>
  <button type="submit" [disabled]="myForm.invalid">Send</button>
</form>

Этот код проверяет, взаимодействовал ли пользователь с полем (dirty или touch). Затем, если значение не соответствует требованиям проверки, будет отображаться сообщение об ошибке. Кнопка «Отправить» также будет отключена до тех пор, пока не будут устранены все проблемы со значениями формы.

Существует несколько способов получения значений элементов управления формы. В этом примере используется myForm.get(name), который эквивалентен myForm.controls.name. Информацию об ошибке можно получить с помощью .hasError(required) или .errors.required.

Заключение

В этой статье вы узнали, как можно применить реактивные формы к примеру приложения Angular. Вы использовали FormControl, FormGroup, FormBuilder и Validators для создания примера формы с проверкой. Для получения дополнительной функциональности обратитесь к официальной документации.

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