Avatar ·

Ошибка: Can't bind to 'formControl' since it isn't a known property of 'input' в Angular Material

Всем привет! Я новичок в Angular и TypeScript, и у меня возникла проблема при попытке использовать автозаполнение из Angular Material. Я создал компонент с полем ввода и хочу привязать к нему `formControl` для управления состоянием формы. Вот мой код: **app.component.ts:** ```typescript import { Component, OnInit } from '@angular/core'; import { FormControl } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { myControl = new FormControl(''); options: string[] = ['One', 'Two', 'Three']; ngOnInit() {} } ``` **app.component.html:** ```html {{ option }} ``` Но когда я запускаю приложение, в консоли появляется ошибка: ``` Can't bind to 'formControl' since it isn't a known property of 'input'. ``` Я импортировал `FormsModule` и `ReactiveFormsModule` в `app.module.ts`: ```typescript import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatInputModule } from '@angular/material/input'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, FormsModule, ReactiveFormsModule, MatAutocompleteModule, MatInputModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule {} ``` Что я делаю не так? Почему Angular не видит свойство `formControl` для тега ``? Помогите, пожалуйста, разобраться! <<>>

Проблема: отсутствует импорт MatFormFieldModule

Причина ошибки в том, что Angular Material требует явного импорта модуля MatFormFieldModule для корректной работы директивы formControl внутри <mat-form-field>. Без этого модуля Angular не распознает formControl как допустимое свойство для элемента <input>, даже если ReactiveFormsModule импортирован.

Решение: добавьте MatFormFieldModule в imports

Вам нужно импортировать MatFormFieldModule из @angular/material/form-field и добавить его в массив imports вашего модуля. Вот исправленный код:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field'; // <- добавить этот импорт
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    MatAutocompleteModule,
    MatInputModule,
    MatFormFieldModule // <- добавить сюда
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

Почему это работает?

  • MatFormFieldModule предоставляет директиву mat-form-field и обеспечивает интеграцию с реактивными формами Angular. Он регистрирует formControl как допустимое свойство для элементов внутри <mat-form-field>.
  • Без него Angular не знает, что <input> находится в контексте Material Form Field, и поэтому игнорирует привязку [formControl].
  • Обратите внимание, что FormsModule и ReactiveFormsModule всё равно нужны — они отвечают за общую работу с формами в Angular.

Дополнительные рекомендации

Если после добавления модуля ошибка остаётся, проверьте следующее:

  • Версии пакетов: убедитесь, что версии @angular/material и @angular/forms совместимы. Для Angular 15+ используйте @angular/material@15 или новее.
  • BrowserAnimationsModule: для корректной работы анимаций Material добавьте BrowserAnimationsModule из @angular/platform-browser/animations.
  • Порядок импорта: обычно порядок не важен, но для избежания конфликтов размещайте BrowserModule первым.

После внесения изменений перезапустите сервер разработки (команда ng serve). Ошибка должна исчезнуть, и автозаполнение заработает.

<<>>

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

Если по каким-то причинам вы не хотите использовать реактивные формы, можно применить ngModel для двустороннего связывания данных. Это более простой способ, но он менее гибкий для сложных сценариев валидации.

Пример компонента с ngModel:

// app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  selectedValue: string = '';
  options: string[] = ['One', 'Two', 'Three'];
}
<!-- app.component.html -->
<mat-form-field>
  <input type="text" placeholder="Выберите значение" [(ngModel)]="selectedValue" [matAutocomplete]="auto">
  <mat-autocomplete #auto="matAutocomplete">
    <mat-option *ngFor="let option of options" [value]="option">{{ option }}</mat-option>
  </mat-autocomplete>
</mat-form-field>

При этом в модуле достаточно импортировать FormsModule (без ReactiveFormsModule), а также MatFormFieldModule и MatInputModule.

Когда выбирать этот вариант?

  • Если ваша форма простая и не требует сложной валидации или динамического управления.
  • Если вы только начинаете изучать Angular и хотите избежать дополнительной сложности реактивных форм.
  • Но помните: для продвинутых сценариев (кастомные валидаторы, отслеживание изменений) реактивные формы (formControl) предпочтительнее.

В любом случае, не забывайте импортировать MatFormFieldModule — это обязательное условие для работы <mat-form-field> в Angular Material.