Einleitung: Warum schreit Ihr Angular-Formular nach einem Fehler?
\nHaben Sie schon einmal die Situation erlebt: Sie schreiben ein schönes Formular mit Angular Material, alles scheint perfekt, aber die Browser-Konsole gibt plötzlich die Meldung aus:
\nmat-form-field must contain a MatFormFieldControl\nOder, wenn Sie den strikten TypeScript-Modus verwenden, könnte so etwas erscheinen:
\nError: mat-form-field must contain a MatFormFieldControl. Did you forget to add a directive that implements MatFormFieldControl?\nDies ist einer der häufigsten Fehler auf Stack Overflow (tausende Aufrufe!), und heute werden wir ihn gründlich analysieren. Sie erfahren nicht nur wie Sie das Problem beheben, sondern auch warum es auftritt. Und vor allem lernen Sie, Ihre eigenen Steuerelemente für Angular Material zu erstellen, falls das Standard-MatInput für Sie nicht geeignet ist.
Los geht's! 🚀
\n\nWas ist MatFormFieldControl und wozu wird es benötigt?
\nBevor wir den Fehler beheben, lassen Sie uns die Anatomie von Angular Material verstehen. mat-form-field ist ein Container, der Material Design-Stilisierung (Label, Unterstreichung, Hinweise, Fehler) hinzufügt. Aber allein zeigt er nichts an. Er benötigt ein "Kind" – eine Direktive oder eine Komponente, die das Interface MatFormFieldControl implementiert.
Dieses Interface (oder die abstrakte Klasse) beschreibt, wie das Steuerelement mit dem Formular interagiert: wie es einen Wert erhält, wie es einen Fehler anzeigt, wie es den Fokus behandelt. Die Standardimplementierung ist MatInput. Wenn Sie schreiben:
<mat-form-field>\n <input matInput placeholder="Name">\n</mat-form-field>\n– dann implementiert die Direktive matInput automatisch MatFormFieldControl.
Der Fehler tritt auf, wenn Angular kein untergeordnetes Element mit einer solchen Implementierung findet. Zum Beispiel:
\n<mat-form-field>\n <input placeholder="Name"> <!-- Kein matInput! -->\n</mat-form-field>\nOder wenn Sie versuchen, eine benutzerdefinierte Komponente zu verwenden, die das Interface nicht eingebunden hat.
\n\nTypische Ursachen des Fehlers (und wie man sie behebt)
\n\n1. Vergessen, die Direktive matInput hinzuzufügen
\nDer trivialste Grund. Sie haben einfach matInput nicht am <input>-Element angegeben.
Falsch:
\n<mat-form-field>\n <input placeholder="E-Mail">\n</mat-form-field>\nRichtig:
\n<mat-form-field>\n <input matInput placeholder="E-Mail">\n</mat-form-field>\nÜberprüfen Sie auch, ob Sie MatInputModule in Ihr Modul importiert haben:
import { MatInputModule } from '@angular/material/input';\n\n@NgModule({\n imports: [MatInputModule]\n})\nexport class AppModule { }\n\n2. Verwendung des falschen HTML-Elements
\nMatInput funktioniert nur mit <input> und <textarea>. Wenn Sie versuchen, ein normales <div> oder <select> (ohne mat-select) in mat-form-field zu verpacken, erhalten Sie den Fehler.
Falsch:
\n<mat-form-field>\n <div>Irgendein Inhalt</div>\n</mat-form-field>\nRichtig: Verwenden Sie die entsprechenden Material-Komponenten:
\n<mat-form-field>\n <mat-select placeholder="Stadt">\n <mat-option value="1">Berlin</mat-option>\n </mat-select>\n</mat-form-field>\nFür mat-select müssen Sie MatSelectModule importieren.
3. Benutzerdefinierte Komponente implementiert MatFormFieldControl nicht
\nDies ist ein komplexerer Fall. Angenommen, Sie haben Ihre eigene Komponente für die Datumseingabe oder Bewertung erstellt. Angular Material weiß nichts darüber. Sie müssen es explizit "beibringen".
\n