mat-form-field debe contener un MatFormFieldControl


189

Estamos tratando de construir nuestros propios componentes de campo de formulario en nuestra empresa. Estamos tratando de envolver los componentes del diseño de materiales de esta manera:

campo:

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

caja de texto:

<field hint="hint">
    <input matInput 
    [placeholder]="placeholder" 
    [value]="value"
    (change)="onChange($event)" 
    (keydown)="onKeydown($event)" 
    (keyup)="onKeyup($event)" 
    (keypress)="onKeypress($event)">
</field>

Uso:

<textbox value="test" hint="my hint"></textbox>

Esto da como resultado aproximadamente esto:

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

Pero obtengo "mat-form-field debe contener un MatFormFieldControl" en la consola. Supongo que esto tiene que ver con mat-form-field que no contiene directamente un matInput-field. Pero lo está conteniendo, solo está dentro de la proyección de contenido ng.

Aquí hay un bombardeo: https://stackblitz.com/edit/angular-xpvwzf


3
¿Alguna vez resolviste el problema? Tengo exactamente el mismo problema. Las respuestas no son relevantes.
numsu

No, desafortunadamente no :/. Encontré esto: github.com/angular/material2/issues/9411 y si entiendo esto correctamente, este es un cajero automático no compatible.
Viktor Eriksson el

Ok .. Gracias, terminé haciendo un componente que simplemente resume todas las sugerencias y validaciones y lo coloqué debajo del elemento de entrada.
numsu

@ViktorEriksson Si mi respuesta fue útil para usted, ¿le gustaría aceptarla?
darksoulsong

1
Lo siento, pero no fue útil, mi pregunta tiene muy poco que ver con esa respuesta.
Viktor Eriksson

Respuestas:


28

Desafortunadamente, la proyección de contenido en mat-form-field aún no es compatible. Siga el siguiente problema de github para obtener las últimas noticias al respecto.

Por ahora, la única solución para usted es colocar su contenido directamente en el componente mat-form-field o implementar una clase MatFormFieldControl creando así un componente de campo de formulario personalizado.


133
Encontré esta pregunta buscando en Google un mensaje de error. La respuesta a continuación , que indica que MatInputModuledebe importarse, resolvió mi problema. Como esta es la respuesta aceptada, agrego el enlace aquí, con la esperanza de que ahorre tiempo a los demás.
CGFoX

44
Mi problema era que había olvidado importar ' FormsModule '. Espero que esto ayude a alguien.
lerenau

@CGFoX ¡Tienes toda la razón, amigo! ¡importar MatInputModule resolvió mi problema!
Rafique Mohammed

55
También dentro de una <mat-form-field>etiqueta debe asegurarse de agregar correctamente el matInputatributo en cada inputetiqueta o matNativeControlatributo en cada<select>
svassr

1
@CGFoX Desearía que actualizaran la documentación con esta información y mejores ejemplos ...

412

Tuve este problema Importé MatFormFieldModuleen mi módulo principal, pero olvidé agregar MatInputModulea la importsmatriz, así:

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

@NgModule({
    imports: [
        MatFormFieldModule,
        MatInputModule
    ]
})
export class AppModule { }

Espero eso ayude.

Más información aquí .


9
También dentro de una <mat-form-field>etiqueta debe asegurarse de agregar correctamente el matInputatributo en cada inputetiqueta o matNativeControlatributo en cada <select>etiqueta
svassr

Gracias. Resuelto mi problema Soy nuevo en material angular. Parece que necesito importar muchos, muchos módulos para usar el material angular. Por ejemplo, necesitamos importar "MatButtonModule" para usar botones, "MatCheckboxModule" para usar casillas de verificación, "MatFormFieldModule" para usar formularios, "MatInputModule" para usar la entrada ... Es realmente agotador. ¿Hay alguna manera de importar solo una o dos veces y luego podríamos comenzar a usar el material angular sin más preocupaciones?
William Hou

1
IMPORTANTE: ¡El orden importa!
Becario Senior

no funciona para mí, acabo de usar este ejemplo: material.angular.io/components/stepper/overview
tatsu

Esto funcionó para mí import { MatInputModule } from '@angular/material/input':
Jared Whipple

86

Solución 1 - importar MatInputModule

importar MatInputModuledentro del módulo, es decirapp.module.ts

Angular 9+

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

Por debajo del angular 9

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

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

Solución 2 - Error de ortografía

Asegúrese de agregar matInputy es sensible a mayúsculas y minúsculas.

<input matInput type="text" />

2
Ahh esto me estaba volviendo loco. La razón uno funcionó para mí. Siento que eso debería especificarse en la documentación, aunque ahora parece obvio.
Fingir

Encontré este problema cuando faltaba "matInput" en la declaración de entrada.
HadidAli

17

Citando de la documentación oficial aquí :

Error: mat-form-field debe contener un MatFormFieldControl

Este error se produce cuando no ha agregado un control de campo de formulario a su campo de formulario. Si su campo de formulario contiene un elemento o elemento nativo, asegúrese de haberle agregado la directiva matInput y haber importado MatInputModule. Otros componentes que pueden actuar como control de campo de formulario incluyen, y cualquier control de campo de formulario personalizado que haya creado.


14

Esto también puede suceder si tiene una entrada adecuada dentro de un campo de formulario mat , pero tiene una entrada ngIf. P.ej:

<mat-form-field>
    <mat-chip-list *ngIf="!_dataLoading">
        <!-- other content here -->
    </mat-chip-list>
</mat-form-field>

En mi caso, mat-chip-listse supone que "aparece" solo después de cargar sus datos. Sin embargo, la validación se realiza y se mat-form-fieldqueja con

mat-form-field debe contener un MatFormFieldControl

Para solucionarlo, el control debe estar allí, así que he usado [hidden]:

<mat-form-field>
    <mat-chip-list [hidden]="_dataLoading">
        <!-- other content here -->
    </mat-chip-list>
</mat-form-field>

Una solución alternativa es propuesta por Mosta: move * ngIf para mat-form-field:

<mat-form-field *ngIf="!_dataLoading">
    <mat-chip-list >
        <!-- other content here -->
    </mat-chip-list>
</mat-form-field>

Acabo de tener un problema similar, lo arreglé con algo similar a lo que estás diciendo. Tienes mi voto a favor!
Alex

3
Gracias, en lugar de usar oculto, puede mover la condición ngIf en toda la etiqueta mat-form-field
Mosta

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



@NgModule({
    imports: [
        MatInputModule
    ],
    exports: [
        MatInputModule
    ]
})

3
Bienvenido a stackoverflow. Al responder preguntas, agregue alguna explicación sobre lo que hace su fragmento de código y por qué resuelve la pregunta del OP. Para obtener más información, consulte aquí Cómo responder
Djensen

6

No estoy seguro de si podría ser así de simple, pero tuve el mismo problema, cambiar "mat-input" a "matInput" en el campo de entrada resolvió el problema. En su caso, veo "matinput" y está causando que mi aplicación arroje el mismo error.

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

ingrese la descripción de la imagen aquí

"matInput"

ingrese la descripción de la imagen aquí


hmm no estoy seguro, has pegado la salida generada. En el código real, ya es matInput, si ve "textbox-section". No tengo problemas para que funcione cuando solo uso material, es cuando trato de hacer que mi propio componente con proyección deje de funcionar. Parece que mi saqueador tiene problemas con el cajero automático, espero que se solucione durante el día.
Viktor Eriksson

Oh ya veo, mi mal. Esta fue una posibilidad remota de todos modos. Seguiré para ver si alguien puede llegar al ángulo de inclinación correcto, tengo curiosidad sobre este problema.
VolverTable

2
Sucedió conmigo, me he olvidado de cambiar mdInputa matInput.
Ebraheem Alrabee '

2
Angular 5: el atributo de etiqueta <input> debe ser en matInputlugar de mat-input.
Stavm

6

Si alguien se atascó con este error después de intentar anidar a <mat-checkbox>, ¡anímate! No funciona dentro de una <mat-form-field>etiqueta.


6

si alguien está tratando de anidar un <mat-radio-group>interior <mat-form-field> como el siguiente, obtendrá este error

         <mat-form-field>
                <!-- <mat-label>Image Position</mat-label> -->
                <mat-radio-group aria-label="Image Position" [(ngModel)]="section.field_1">
                    <mat-radio-button value="left">Left</mat-radio-button>
                    <mat-radio-button value="right">Right</mat-radio-button>
                </mat-radio-group>
            </mat-form-field>

eliminar las <mat-form-field>etiquetas principales


Estaba teniendo este problema y tenía un fragmento de marcado con este tipo de cosas. Eliminarlo mat-form-fieldhizo que el problema desapareciera para mí.
Andrew Gray

¿Hay alguna razón que <mat-form-field>no sea compatible con el grupo de radio dentro de él? También estaba teniendo este problema y no pensé en eliminar las etiquetas de campo de formulario de estera porque no parecía que fuera lo correcto, ya que se usan muchos materiales de ejemplos de formularios de interfaz de usuario <mat-form-field>. Tengo todos los diversos módulos de entrada de formularios de materiales para formularios, menús desplegables seleccionados y grupos de radio definidos en mi app.module.ts como muchas de las otras referencias de respuestas.
Alex

No puedo creer ... Intento todo y nada para trabajar ... y después de unos días de dolor encontré esta solución tan simple ... gracias amigo
Arter

4

También tuve este problema, y ​​tengo un <mat-select>elemento en mi plantilla, cuando importo el MatSelectModule en el Módulo, funciona, no hace ciencia, pero espero que pueda ayudarlo.

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>

Funciona ya que sin importar el módulo, el control mat-form-field no comprende qué es un mat-select. Cuando se importa, puede corregir toda la información y, por lo tanto, puede analizar la plantilla sin más errores.
PeterS

3

Desafortunadamente, no puedo comentar algunas respuestas ya buenas, ya que todavía no tengo los puntos SO, sin embargo, hay 3 módulos clave que necesitará para asegurarse de que está importando al módulo principal de su componente, aparte de lo que tienes que importar directamente a tu componente. Quería compartirlos brevemente y resaltar lo que hacen.

  1. MatInputModule
  2. MatFormFieldModule
  3. ReactiveFormsModule

Los dos primeros son para material angular. Muchas personas nuevas en Angular Material se encontrarán instintivamente con uno de estos y no se darán cuenta de que construir una forma requiere ambos.

Entonces, ¿cuál es la diferencia entre ellos?

MatFormFieldModule abarca todos los diferentes tipos de campos de formulario que Angular Material tiene disponible. Este es más un módulo de alto nivel para campos de formulario en general, mientras que MatInputModule es específicamente para tipos de campo de 'entrada', en lugar de cuadros de selección, botones de opción, etc.

El tercer elemento en la lista anterior es el Módulo de formularios reactivos de Angular. El módulo de formas reactivas es responsable de una tonelada de amor angular bajo el capó. Si vas a trabajar con Angular, te recomiendo que pases un tiempo leyendo Angular Docs. Tienen todas tus respuestas. La creación de aplicaciones rara vez NO involucra formularios, y la mayoría de las veces, su aplicación incluirá formularios reactivos. Por esa razón, tómese el tiempo de leer estas dos páginas.

Documentos angulares: formas reactivas

Documentos angulares: módulo de formularios reactivos

El primer documento 'Formas reactivas' será su arma más poderosa cuando comience, y el segundo documento será su arma más poderosa a medida que avance en aplicaciones más avanzadas de Formas reactivas angulares.

Recuerde, estos deben importarse directamente en el módulo de su componente, no en el componente en el que los está utilizando. Si no recuerdo mal, en Angular 2, importamos el conjunto completo de módulos de material angular en nuestro módulo de aplicación principal, y luego importamos qué Necesitábamos en cada uno de nuestros componentes directamente. El método actual es una OMI mucho más eficiente porque estamos garantizados para importar el conjunto completo de módulos de material angular si solo usamos algunos de ellos.

Espero que esto proporcione un poco más de información sobre la creación de formas con material angular.


3

Si todas las respuestas de configuración / estructura del código principal anteriores no resuelven su problema, aquí hay una cosa más que debe verificar: asegúrese de no haber invalidado de alguna manera su <input>etiqueta.

Por ejemplo, recibí el mismo mat-form-field must contain a MatFormFieldControlmensaje de error después de colocar accidentalmente un requiredatributo después de una barra oblicua /, lo que efectivamente invalidó mi <input/>. En otras palabras, hice esto (ver el final de los atributos de la etiqueta de entrada):

mal :

<input matInput type="text" name="linkUrl" [formControl]="listingForm.controls['linkUrl']" /required>

derecha :

<input matInput type="text" name="linkUrl" [formControl]="listingForm.controls['linkUrl']" required/>

Si comete ese error u otra cosa para invalidar su <input>, entonces podría obtener el mat-form-field must contain a MatFormFieldControlerror. De todos modos, esto es solo una cosa más a tener en cuenta mientras estás depurando.


3

El mismo error puede ocurrir si tiene una diapositiva de mat dentro de un campo de mat como el único elemento en mi caso que tuve

 <mat-form-field>
    <mat-slide-toggle [(ngModel)]="myvar">
       Some Text
     </mat-slide-toggle>
 </mat-form-field>

Esto podría suceder si tuviera varios atributos dentro de la <mat-form-field> solución simple: mover la diapositiva a la raíz


1
Esto me salvó la vida. Gracias.
Paulo Pedroso

2

Puede intentar seguir esta guía e implementar / proporcionar su propio MatFormFieldControl


2

Accidentalmente eliminé la directiva matInput del campo de entrada que causó el mismo error.

p.ej.

<mat-form-field>
   <input [readOnly]="readOnly" name="amount" formControlName="amount" placeholder="Amount">
</mat-form-field>

código fijo

 <mat-form-field>
   <input matInput [readOnly]="readOnly" name="amount" formControlName="amount" placeholder="Amount">
</mat-form-field>

2

MatRadioModule no funcionará dentro de MatFormField. Los documentos dicen

Este error se produce cuando no ha agregado un control de campo de formulario a su campo de formulario. Si su campo de formulario contiene un elemento o elemento nativo, asegúrese de haberle agregado la directiva matInput y haber importado MatInputModule. Otros componentes que pueden actuar como control de campo de formulario incluyen <mat-select>, <mat-chip-list> y cualquier control de campo de formulario personalizado que haya creado.


2

En mi caso, uno de mis paréntesis de cierre para "onChanges ()" se perdió en el elemento de entrada y, por lo tanto, el elemento de entrada aparentemente no se representaba en absoluto:

<input mat-menu-item 
      matInput type="text" 
      [formControl]="myFormControl"
      (ngModelChange)="onChanged()>

2

Una solución parcial es envolver el campo de formulario de material en un componente personalizado e implementar el ControlValueAccessor interfaz en él. Además de la proyección de contenido, el efecto es prácticamente el mismo.

Ver ejemplo completo en Stackblitz.

Usé FormControl( formas reactivas ) dentro CustomInputComponentpero FormGroupoFormArray debería funcionar también si usted necesita un elemento de forma más compleja.

app.component.html

<form [formGroup]="form" (ngSubmit)="onSubmit()">

  <mat-form-field appearance="outline" floatLabel="always" color="primary">
    <mat-label>First name</mat-label>
    <input matInput placeholder="First name" formControlName="firstName" required>
    <mat-hint>Fill in first name.</mat-hint>
    <mat-error *ngIf="firstNameControl.invalid && (firstNameControl.dirty || firstNameControl.touched)">
      <span *ngIf="firstNameControl.hasError('required')">
        You must fill in the first name.
      </span>
    </mat-error>
  </mat-form-field>

  <custom-input
    formControlName="lastName"
    [errorMessages]="errorMessagesForCustomInput"
    [hint]="'Fill in last name.'"
    [label]="'Last name'"
    [isRequired]="true"
    [placeholder]="'Last name'"
    [validators]="validatorsForCustomInput">
  </custom-input>

  <button mat-flat-button
    color="primary"
    type="submit"
    [disabled]="form.invalid || form.pending">
    Submit
  </button>

</form>

custom-input.component.html

<mat-form-field appearance="outline" floatLabel="always" color="primary">
  <mat-label>{{ label }}</mat-label>

  <input
    matInput
    [placeholder]="placeholder"
    [required]="isRequired"
    [formControl]="customControl"
    (blur)="onTouched()"
    (input)="onChange($event.target.value)">
  <mat-hint>{{ hint }}</mat-hint>

  <mat-error *ngIf="customControl.invalid && (customControl.dirty || customControl.touched)">
    <ng-container *ngFor="let error of errorMessages">
    <span *ngFor="let item of error | keyvalue">
      <span *ngIf="customControl.hasError(item.key)">
        {{ item.value }}
      </span>
    </span>
    </ng-container>
  </mat-error>
</mat-form-field>


2

Debe importar MatInputModule en su archivo app.module.ts

importar {MatInputModule} desde '@ angular / material';

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { IonicModule } from '@ionic/angular';
import { CustomerPage } from './components/customer/customer';
import { CustomerDetailsPage } from "./components/customer-details/customer-details";
import { CustomerManagementPageRoutingModule } from './customer-management-routing.module';
import { MatAutocompleteModule } from '@angular/material/autocomplete'
import { ReactiveFormsModule } from '@angular/forms';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule} from '@angular/material';

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    CustomerManagementPageRoutingModule,
    MatAutocompleteModule,
    MatInputModule,
    ReactiveFormsModule,
    MatFormFieldModule
  ],

2

Puede establecer apariencia = "relleno" dentro de su etiqueta mat-form-field, funciona para mí

<form class="example-form">
  <mat-form-field class="example-full-width" appearance="fill">
    <mat-label>Username Or Email</mat-label>
    <input matInput placeholder="Username Or Email" type="text">
  </mat-form-field>

  <mat-form-field class="example-full-width" appearance="fill">
    <mat-label>Password</mat-label>
    <input matInput placeholder="Password" type="password">
  </mat-form-field>
</form>

Esto solucionó mi problema. ¿Puede explicar qué appearence = "fill"está haciendo aquí?
IamGrooot

2

Angular 9+ ... Material 9+

He notado que 3 errores pueden dar lugar al mismo error:

  1. Asegúrese de haber importado MatFormFieldModule y MatInputModule en app.module o module.ts donde se importan sus componentes (en el caso de módulos anidados)
  2. Cuando envuelve botones de material o casillas de verificación en mat-form-field. Consulte la lista de componentes de material que se pueden envolver con mat-form-field mat-form-field
  3. Cuando no puede incluir matInput en su etiqueta. es decir, <input matInput type = "number" step = "0.01" formControlName = "price" />


1

En mi caso cambié esto:

<mat-form-field>
  <input type="email" placeholder="email" [(ngModel)]="data.email">
</mat-form-field>

a esto:

<mat-form-field>
  <input matInput type="email" placeholder="email" [(ngModel)]="data.email">
</mat-form-field>

Agregar la directiva matInput a la etiqueta de entrada fue lo que solucionó este error para mí.



1

usar proveedores en el archivo component.ts

@Component({
 selector: 'your-selector',
 templateUrl: 'template.html',
 styleUrls: ['style.css'],
 providers: [
 { provide: MatFormFieldControl, useExisting: FormFieldCustomControlExample }   
]
})

0

Nota En algún momento se produce un error, cuando usamos la etiqueta "mat-form-field" alrededor del botón de envío como:

<mat-form-field class="example-full-width">
   <button mat-raised-button type="submit" color="primary">  Login</button>
   </mat-form-field>

Así que amablemente no use esta etiqueta alrededor del botón Enviar


0

Tuve el mismo problema

el problema es simple

solo debes importar dos módulos a tu proyecto

MatFormFieldModule MatInputModule


0

Estaba recibiendo el mismo problema debido al elemento comentado de la siguiente manera.

<mat-form-field>
    <mat-label>Database</mat-label>
    <!-- <mat-select>
        <mat-option *ngFor="let q of queries" [value]="q.id">
            {{q.name}}
        </mat-option>
    </mat-select>  -->
</mat-form-field>

¡El campo de formulario debe tener elemento! (por ejemplo, la entrada, el área de texto, select, etc.)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.