Ошибка Angular: "There is no directive with exportAs set to ngForm" при работе с формами
Причина ошибки
Ошибка "There is no directive with exportAs set to ngForm" возникает, когда Angular не может найти директиву NgForm, экспортирующую себя под именем ngForm. Это происходит, если FormsModule не импортирован в ваш модуль или импортирован неправильно. Даже если вы думаете, что импортировали его, ошибка может быть связана с тем, что вы импортируете FormsModule в AppModule, но ваш компонент объявлен в другом модуле (например, в FeatureModule), который не импортирует FormsModule.
Решение
Убедитесь, что FormsModule импортирован в тот модуль, где объявлен ваш компонент. Чаще всего это AppModule, но если у вас есть модули с ленивой загрузкой, импорт нужно делать в каждый из них. Вот правильный пример:
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; // <-- обязательно импортировать
import { AppComponent } from './app.component';
import { UserRegistrationComponent } from './user-registration/user-registration.component';
@NgModule({
declarations: [
AppComponent,
UserRegistrationComponent // <-- компонент объявлен здесь
],
imports: [
BrowserModule,
FormsModule // <-- FormsModule добавлен в imports
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Пошаговая проверка
- Проверьте импорт в модуле: Убедитесь, что строка
import { FormsModule } from '@angular/forms';присутствует в файле модуля. - Проверьте массив imports:
FormsModuleдолжен быть в массивеimports, а не вdeclarationsилиproviders. - Если у вас несколько модулей: Каждый модуль, который использует
ngModelилиngForm, должен импортироватьFormsModule. - Проверьте версию Angular: В старых версиях (2.x)
FormsModuleмог быть в другом пакете. Убедитесь, что используете актуальные версии. - Перезапустите сервер: После добавления импорта обязательно перезапустите сервер разработки (
ng serve), так как изменения в модулях не применяются горячей перезагрузкой.
Дополнительная проверка
Если ошибка всё ещё появляется, проверьте, не импортировали ли вы случайно ReactiveFormsModule вместо FormsModule. Для шаблонных форм (template-driven forms) нужен именно FormsModule. ReactiveFormsModule используется для реактивных форм и не содержит директивы ngForm.
// Неправильно:
import { ReactiveFormsModule } from '@angular/forms'; // это для реактивных форм
// Правильно:
import { FormsModule } from '@angular/forms'; // для шаблонных форм
Проверка на опечатки
Убедитесь, что в шаблоне вы используете именно #myForm="ngForm" (с маленькой буквы 'n' в 'ngForm'). Angular чувствителен к регистру, и #myForm="ngform" или #myForm="NgForm" вызовут эту же ошибку.
После всех этих исправлений ваша форма должна работать корректно, и вы сможете использовать myForm.valid, myForm.submitted и другие свойства директивы NgForm.
Альтернативный подход: использование реактивных форм
Если вы не хотите разбираться с шаблонными формами или вам нужна более сложная валидация, рассмотрите использование реактивных форм (Reactive Forms). Они не используют директиву ngForm, поэтому ошибка "There is no directive with exportAs set to ngForm" не возникнет.
// app.module.ts
import { ReactiveFormsModule } from '@angular/forms'; // импортируем ReactiveFormsModule
@NgModule({
imports: [
BrowserModule,
ReactiveFormsModule // <-- используем реактивные формы
]
})
export class AppModule { }
// user-registration.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-user-registration',
templateUrl: './user-registration.component.html'
})
export class UserRegistrationComponent implements OnInit {
registrationForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.registrationForm = this.fb.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(6)]]
});
}
onSubmit() {
if (this.registrationForm.valid) {
console.log('Форма отправлена', this.registrationForm.value);
}
}
}
<!-- user-registration.component.html -->
<form [formGroup]="registrationForm" (ngSubmit)="onSubmit()">
<div>
<label>Email:</label>
<input type="email" formControlName="email">
<div *ngIf="registrationForm.get('email')?.invalid && registrationForm.get('email')?.touched">
Введите корректный email
</div>
</div>
<div>
<label>Пароль:</label>
<input type="password" formControlName="password">
</div>
<button type="submit" [disabled]="!registrationForm.valid">Зарегистрироваться</button>
</form>
Реактивные формы дают больше контроля над валидацией и состоянием формы, а также легче тестируются. Однако для простых форм шаблонный подход с FormsModule часто оказывается удобнее.
Ответов пока нет.
Войдите чтобы оставить ответ