Avatar ·

Ошибка "mat-form-field must contain a MatFormFieldControl" в Angular Material

Всем привет! Я новичок в Angular и Angular Material. Пытаюсь сделать простую форму с текстовым полем, но получаю ошибку в консоли: "mat-form-field must contain a MatFormFieldControl". У меня Angular 15 и Angular Material. Вот мой код компонента: **app.component.ts:** ```typescript import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'my-form-app'; } ``` **app.component.html:** ```html ``` Я импортировал MatFormFieldModule в app.module.ts: ```typescript import { MatFormFieldModule } from '@angular/material/form-field'; @NgModule({ imports: [MatFormFieldModule], ... }) ``` Но всё равно ошибка. Я пробовал добавить MatInputModule, но не помогло. Что я делаю не так? Как правильно использовать mat-form-field с input? Может быть, я неправильно импортирую модули? Заранее спасибо за помощь! <<>>

Причина ошибки

Ошибка возникает, потому что Angular Material ожидает, что внутри <mat-form-field> будет находиться специализированный контрол, реализующий интерфейс MatFormFieldControl. Обычный HTML-элемент <input type="text"> не является таким контролом. Для работы с текстовыми полями в Angular Material используется директива matInput, которая подключается через модуль MatInputModule.

Решение

Вам нужно:

  1. Импортировать MatInputModule в ваш модуль
  2. Добавить директиву matInput к элементу <input>
  3. Убрать лишний тег <label> (или использовать mat-label)

Шаг 1: Импорт модулей

В app.module.ts импортируйте оба модуля:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { AppComponent } from './app.component';

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

Шаг 2: Исправьте шаблон

В app.component.html используйте правильную структуру:

<mat-form-field appearance="outline">
  <mat-label>Имя пользователя</mat-label>
  <input matInput type="text" placeholder="Введите имя">
</mat-form-field>

Ключевые моменты:

  • matInput — директива, которая связывает элемент input с mat-form-field
  • mat-label — правильный способ задания подписи (вместо обычного <label>)
  • appearance — необязательный атрибут для стилизации (fill, outline, legacy)
  • Обязательно импортируйте BrowserAnimationsModule для анимаций Material

Шаг 3: Проверка импортов

Если ошибка остаётся, проверьте:

  • Установлены ли пакеты: npm install @angular/material @angular/cdk @angular/animations
  • Добавлен ли стиль темы Material в angular.json или styles.scss: @import '@angular/material/prebuilt-themes/indigo-pink.css';
  • Не забыли ли вы MatInputModule — это самая частая причина ошибки

Полный рабочий пример

Вот минимальный рабочий компонент:

// app.component.ts
import { Component } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  template: `
    <mat-form-field>
      <mat-label>Email</mat-label>
      <input matInput [formControl]="emailControl" placeholder="example@mail.com">
      <mat-error *ngIf="emailControl.invalid">Введите корректный email</mat-error>
    </mat-form-field>
  `
})
export class AppComponent {
  emailControl = new FormControl('', [Validators.email, Validators.required]);
}

Не забудьте также импортировать ReactiveFormsModule в модуль, если используете formControl.

<<>>

Альтернативный подход: использование matNativeControl

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

<mat-form-field>
  <mat-label>Имя</mat-label>
  <input matNativeControl type="text">
</mat-form-field>

Недостатки:

  • Не поддерживает кастомные контролы (календари, селекты)
  • Ограниченная стилизация
  • Нет интеграции с реактивными формами (formControl) без дополнительных настроек

Диагностика проблемы

Если оба решения не работают, проверьте:

  1. Версию Angular Material — для Angular 15+ используйте @angular/material@15
  2. Наличие <router-outlet> или других структур, которые могут "разрывать" DOM — mat-form-field должен быть прямым родителем контрола
  3. Консоль браузера на наличие других ошибок, которые могут блокировать загрузку модулей

Рекомендую всегда использовать matInput — это стандартный и самый поддерживаемый способ.