Формы на шаблонах
В Angular два вида форм. Формы на шаблонах (template-driven) описываются прямо в HTML: каждое поле связывают с полем класса директивой ngModel. Они проще и хорошо подходят для небольших форм вроде формы новой статьи.
Подключение FormsModule
Директивы шаблонных форм лежат в FormsModule — его добавляют в imports компонента. Перепишем форму статьи src/app/post-form/post-form.ts:
// src/app/post-form/post-form.ts
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-post-form',
imports: [FormsModule],
templateUrl: './post-form.html',
})
export class PostForm {
post = { title: '', body: '' };
}ngModel
Директива ngModel в двусторонней привязке связывает поле ввода со свойством класса. Атрибут name обязателен — по нему форма узнаёт поле:
<!-- src/app/post-form/post-form.html -->
<input name="title" [(ngModel)]="post.title" placeholder="Заголовок" />
<p>Вы ввели: {{ post.title }}</p>Начните печатать в поле — текст сразу появится под ним. И наоборот: если код изменит post.title, значение в поле тоже поменяется.
Отправка формы
Событие ngSubmit срабатывает при нажатии кнопки отправки или Enter. Angular сам отменяет перезагрузку страницы:
<!-- src/app/post-form/post-form.html -->
<form (ngSubmit)="save()">
<input name="title" [(ngModel)]="post.title" placeholder="Заголовок" />
<textarea name="body" [(ngModel)]="post.body" placeholder="Текст"></textarea>
<button type="submit">Опубликовать</button>
</form>// src/app/post-form/post-form.ts
import { Component, inject, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { PostApi } from '../post-api';
@Component({
selector: 'app-post-form',
imports: [FormsModule],
templateUrl: './post-form.html',
})
export class PostForm {
private api = inject(PostApi);
post = { title: '', body: '' };
message = signal('');
save() {
this.api.createPost({ ...this.post }).subscribe((created) => {
this.message.set(`Статья №${created.id} создана`);
});
}
}Заполните поля и нажмите «Опубликовать» — запрос уйдёт на JSONPlaceholder, и в message появится «Статья №101 создана» (выведите {{ message() }} под формой).
Объект формы
Переменная шаблона со значением ngForm даёт доступ ко всей форме:
<!-- src/app/post-form/post-form.html -->
<form #form="ngForm" (ngSubmit)="save(); form.reset()">
...
</form>
<pre>{{ form.value | json }}</pre>form.value — объект со всеми полями по их name, form.reset() очищает форму. Для пайпа json добавьте JsonPipe из @angular/common в imports.
Флажки и списки
ngModel работает с любыми полями:
<!-- src/app/post-form/post-form.html -->
<label><input type="checkbox" name="draft" [(ngModel)]="draft" /> Черновик</label>
<select name="category" [(ngModel)]="category">
<option value="news">Новости</option>
<option value="howto">Инструкции</option>
</select>Флажок связан с логическим значением, список — со строкой из value выбранного пункта. Поля draft = false и category = 'news' добавьте в класс.
Частая ошибка
Забыть атрибут name у поля внутри <form>. Angular выдаст ошибку о том, что у ngModel внутри тега формы должен быть атрибут name. Каждому полю с ngModel в форме дайте уникальное name.