Nous essayons de construire nos propres composants de champ de formulaire dans notre société. Nous essayons d'encapsuler les composants de conception de matériel comme ceci:
champ:
<mat-form-field>
<ng-content></ng-content>
<mat-hint align="start"><strong>{{hint}}</strong> </mat-hint>
<mat-hint align="end">{{message.value.length}} / 256</mat-hint>
<mat-error>This field is required</mat-error>
</mat-form-field>
zone de texte:
<field hint="hint">
<input matInput
[placeholder]="placeholder"
[value]="value"
(change)="onChange($event)"
(keydown)="onKeydown($event)"
(keyup)="onKeyup($event)"
(keypress)="onKeypress($event)">
</field>
Usage:
<textbox value="test" hint="my hint"></textbox>
Cela se traduit approximativement par ceci:
<textbox placeholder="Personnummer/samordningsnummer" value="" ng-reflect-placeholder="Personnummer/samordningsnummer">
<field>
<mat-form-field class="mat-input-container mat-form-field>
<div class="mat-input-wrapper mat-form-field-wrapper">
<div class="mat-input-flex mat-form-field-flex">
<div class="mat-input-infix mat-form-field-infix">
<input _ngcontent-c4="" class="mat-input-element mat-form-field-autofill-control" matinput="" ng-reflect-placeholder="Personnummer/samordningsnummer" ng-reflect-value="" id="mat-input-2" placeholder="Personnummer/samordningsnummer" aria-invalid="false">
<span class="mat-input-placeholder-wrapper mat-form-field-placeholder-wrapper"></span>
</div>
</div>
<div class="mat-input-underline mat-form-field-underline">
<span class="mat-input-ripple mat-form-field-ripple"></span>
</div>
<div class="mat-input-subscript-wrapper mat-form-field-subscript-wrapper"></div>
</div>
</mat-form-field>
</field>
</textbox>
Mais nous obtenons "mat-form-field doit contenir un MatFormFieldControl" dans la console. Je suppose que cela a à voir avec le mat-form-field ne contenant pas directement un matInput-field. Mais il est en train de le contenir, il s’agit simplement de la projection de contenu ng.
Voici un blitz: https://stackblitz.com/edit/angular-xpvwzf
Malheureusement, la projection de contenu dans mat-form-field n'est pas encore prise en charge. Veuillez suivre ce qui suit numéro de github pour obtenir les dernières nouvelles à ce sujet.
À présent, la seule solution pour vous consiste à placer votre contenu directement dans le composant mat-form-field ou à implémenter une classe MatFormFieldControl, créant ainsi un composant de champ de formulaire personnalisé.
J'ai eu ce problème. J'ai importé MatFormFieldModule
dans mon module principal, mais j'ai oublié d'ajouter MatInputModule
au tableau imports
, comme suit:
import { MatFormFieldModule, MatInputModule } from '@angular/material';
@NgModule({
imports: [
MatFormFieldModule,
MatInputModule
]
})
export class AppModule { }
J'espère que ça aide.
Plus d'infos ici .
importer MatInputModule
dans app.module.ts
import { MatInputModule } from '@angular/material';
@NgModule({
imports: [
// .......
MatInputModule
// .......
]
})
export class AppModule { }
Vérifiez l'orthographe de matInput
, assurez-vous qu'il est sensible à la casse
<input matInput type="text" />
Citant la documentation officielle ici :
Erreur: mat-form-field doit contenir un MatFormFieldControl
Cette erreur se produit lorsque vous n'avez pas ajouté de contrôle de champ de formulaire à votre champ de formulaire. Si votre champ de formulaire contient un élément natif ou un élément, assurez-vous que vous y avez ajouté la directive matInput et importé MatInputModule. Les autres composants pouvant agir en tant que contrôle de champ de formulaire incluent, et tous les contrôles de champ de formulaire personnalisés que vous avez créés.
Cela peut aussi arriver si vous avez ne entrée correcte dans un champ de formulaire, mais il y a un ngIf
. Par exemple.:
<mat-form-field>
<mat-chip-list *ngIf="!_dataLoading">
<!-- other content here -->
</mat-chip-list>
</mat-form-field>
Dans mon cas, mat-chip-list
n'est censé "apparaître" qu'après le chargement de ses données. Cependant, la validation est effectuée et mat-form-field
se plaint auprès de
mat-form-field doit contenir un MatFormFieldControl
Pour résoudre ce problème, le contrôle doit être là, donc j'ai utilisé [hidden]
:
<mat-form-field>
<mat-chip-list [hidden]="_dataLoading">
<!-- other content here -->
</mat-chip-list>
</mat-form-field>
Une solution alternative est proposée par Mosta
: move * ngIf pour mat-form-field
:
<mat-form-field *ngIf="!_dataLoading">
<mat-chip-list >
<!-- other content here -->
</mat-chip-list>
</mat-form-field>
Je ne sais pas si cela pourrait être aussi simple, mais j'avais le même problème. Changer "mat-input" en "matInput" dans le champ de saisie a résolu le problème. Dans votre cas, je vois "matinput" et mon application génère la même erreur.
<input _ngcontent-c4="" class="mat-input-element mat-form-field-autofill-control" matinput="" ng-reflect-placeholder="Personnummer/samordningsnummer" ng-reflect-value="" id="mat-input-2" placeholder="Personnummer/samordningsnummer" aria-invalid="false">
"matinput"
"matInput"
Si quelqu'un se heurte à cette erreur après avoir tenté d'imbriquer un <mat-checkbox>
, soyez de bonne humeur! Cela ne fonctionne pas dans une balise <mat-form-field>
.
J'ai également eu ce problème et j'ai l'élément <mat-select>
dans mon modèle. Lorsque j'importe le MatSelectModule dans Module, cela fonctionne, cela ne fait pas de la science, mais espérons toujours qu'il pourra vous aider.
import { MatSelectModule } from '@angular/material/select';
imports: [
BrowserModule,
BrowserAnimationsModule,
MatSidenavModule,
MatButtonModule,
MatIconModule,
MatToolbarModule,
MatFormFieldModule,
MatProgressSpinnerModule,
MatInputModule,
MatCardModule,
MatSelectModule
],
<div class="example-container">
<mat-form-field>
<input matInput placeholder="Input">
</mat-form-field>
<mat-form-field>
<textarea matInput placeholder="Textarea"></textarea>
</mat-form-field>
<mat-form-field>
<mat-select placeholder="Select">
<mat-option value="option">Option</mat-option>
</mat-select>
</mat-form-field>
</div>
Vous pouvez essayer de suivre ceci guide et implémenter/fournir votre propre MatFormFieldControl
Si toutes les réponses principales concernant la structure/configuration du code ci-dessus ne résolvent pas votre problème, voici une dernière chose à vérifier: assurez-vous que vous n'avez pas invalidé votre balise <input>
.
Par exemple, j'ai reçu le même message d'erreur mat-form-field must contain a MatFormFieldControl
après avoir placé accidentellement un attribut required
après une barre oblique à fermeture automatique /
, qui a effectivement invalidé mon <input/>
. En d'autres termes, j'ai fait ceci (voir la fin des attributs de la balise d'entrée):
faux :
<input matInput type="text" name="linkUrl" [formControl]="listingForm.controls['linkUrl']" /required>
à droite :
<input matInput type="text" name="linkUrl" [formControl]="listingForm.controls['linkUrl']" required/>
Si vous faites cette erreur ou quelque chose d'autre pour invalider votre <input>
, alors vous pourriez obtenir l'erreur mat-form-field must contain a MatFormFieldControl
. Quoi qu'il en soit, il ne s'agit que d'une dernière chose à rechercher lors du débogage.
MatRadioModule ne fonctionnera pas dans MatFormField. Le docs dire
Cette erreur se produit lorsque vous n'avez pas ajouté de contrôle de champ de formulaire à votre champ de formulaire. Si votre champ de formulaire contient un élément natif ou un élément, assurez-vous que vous y avez ajouté la directive matInput et importé MatInputModule. Les autres composants pouvant agir en tant que contrôle de champ de formulaire incluent <sélection-mat>, <liste-mat-chip> et tout champ de formulaire personnalisé vous contrôlant. 'ai créé.
Dans mon cas, une de mes parenthèses fermantes pour "onChanges ()" était manquante sur l'élément d'entrée et par conséquent, l'élément d'entrée n'était apparemment pas rendu du tout:
<input mat-menu-item
matInput type="text"
[formControl]="myFormControl"
(ngModelChange)="onChanged()>
La même erreur peut se produire si vous avez une glissière de tapis dans un tapis de champ comme seul élément dans mon cas que j'avais
<mat-form-field>
<mat-slide-toggle [(ngModel)]="myvar">
Some Text
</mat-slide-toggle>
</mat-form-field>
Cela peut arriver si vous avez plusieurs attributs dans le <mat-form-field>
La solution simple consiste à déplacer le curseur de la diapositive vers la racine.
Malheureusement, je ne peux pas me contenter de commenter certaines réponses déjà bonnes, car je ne dispose pas encore des points SO. Toutefois, il vous faudra 3 modules clés pour vous assurer que vous importez bien dans le composant. module parent, mis à part ce que vous devez importer directement dans votre composant. Je voulais les partager brièvement et souligner ce qu’ils font.
Les deux premiers sont pour Angular Material. Beaucoup de gens nouveaux à Angular Material trouveront instinctivement l'un de ceux-ci sans se rendre compte que la création d'un formulaire requiert les deux.
Alors, quelle est la différence entre eux?
MatFormFieldModule englobe tous les types de champs de formulaire disponibles pour Angular. Il s’agit plus d’un module de haut niveau pour les champs de formulaire en général, alors que MatInputModule est spécifiquement conçu pour les types de champs "entrée", par opposition aux zones de sélection, aux boutons radio, etc.
Le troisième élément de la liste ci-dessus est le module de formulaires réactifs d'Angular. Le module de formulaires réactifs est responsable d'une tonne d'amour Angular sous le capot. Si vous envisagez de travailler avec Angular, je vous recommande vivement de lire un peu de temps Angular Docs. Ils ont toutes vos réponses. Les applications de construction n'impliquent rarement de formulaires, et le plus souvent, votre application comportera des formulaires réactifs. Pour cette raison, veuillez prendre le temps de lire ces deux pages.
Documents angulaires: formes réactives
Documents angulaires: module de formulaires réactifs
Le premier document 'Formulaires réactifs' sera votre arme la plus puissante à vos débuts, et le second document sera votre arme la plus puissante pour passer à des applications plus avancées de Angular Formes réactives.
N'oubliez pas que ces éléments doivent être importés directement dans le module de votre composant, et non pas le composant dans lequel vous les utilisez. Si je me souviens bien, dans Angular 2, nous avons importé l'ensemble complet de Angular. Les modules matériels de notre module principal de l'application, puis importaient directement ce dont nous avions besoin dans chacun de nos composants. La méthode actuelle est beaucoup plus efficace à l’OMI car nous sommes assurés d’importer l’ensemble complet des modules Angular Material si nous n’en utilisons que quelques-uns.
J'espère que cela donne un peu plus de perspicacité dans la création de formes avec Angular Material.
J'avais accidentellement supprimé la directive matInput du champ de saisie qui avait provoqué la même erreur.
par exemple.
<mat-form-field>
<input [readOnly]="readOnly" name="amount" formControlName="amount" placeholder="Amount">
</mat-form-field>
code fixe
<mat-form-field>
<input matInput [readOnly]="readOnly" name="amount" formControlName="amount" placeholder="Amount">
</mat-form-field>
Dans mon cas, j'ai changé ceci:
<mat-form-field>
<input type="email" placeholder="email" [(ngModel)]="data.email">
</mat-form-field>
pour ça:
<mat-form-field>
<input matInput type="email" placeholder="email" [(ngModel)]="data.email">
</mat-form-field>
L'ajout de la directive matInput à la balise input a été ce qui a corrigé cette erreur pour moi.