web-dev-qa-db-fra.com

mat-form-field doit contenir un MatFormFieldControl

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

106
Viktor Eriksson

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é.

12
n.yakovenko

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 .

282
darksoulsong

Solution 1

importer MatInputModule dans app.module.ts

import { MatInputModule } from '@angular/material';

@NgModule({
  imports: [
     // .......
     MatInputModule
     // .......
  ]
})
export class AppModule { }

Solution 2

Vérifiez l'orthographe de matInput, assurez-vous qu'il est sensible à la casse

<input matInput type="text" />
53
WasiF

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.

13
user158

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>
7
Alexei

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"

enter image description here

"matInput"

enter image description here

6
ReturnTable

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>.

3
Mina

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>
2
user9001817

Vous pouvez essayer de suivre ceci guide et implémenter/fournir votre propre MatFormFieldControl

1
rivanov

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.

1
cjn

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éé.

1
intotecho

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()>
1
java-addict301

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.

0
Kamana Kisinga

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.

  1. MatInputModule
  2. MatFormFieldModule
  3. Formulaire de formulaire réactif

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.

0
anothercoder

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>
0
Franklin Pious

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.

0
Gilmourguru