mat-form-field deve contenere un MatFormFieldControl


189

Stiamo provando a costruire i nostri componenti del campo forma presso la nostra azienda. Stiamo cercando di avvolgere i componenti del design del materiale in questo modo:

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>

casella di testo:

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

Ciò si traduce approssimativamente in questo:

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

Ma sto ottenendo "mat-form-field deve contenere un MatFormFieldControl" nella console. Immagino che ciò abbia a che fare con mat-form-field che non contiene direttamente un matInput-field. Ma lo contiene, è solo dentro la proiezione del contenuto di ng.

Ecco un blitz: https://stackblitz.com/edit/angular-xpvwzf


3
Hai mai risolto il problema? Sto avendo lo stesso identico problema. Le risposte non sono rilevanti
numsu,

No, sfortunatamente no :/. Ho trovato questo: github.com/angular/material2/issues/9411 e se lo capisco correttamente, questo non è supportato.
Viktor Eriksson, il

Ok .. Grazie, ho finito per creare un componente che racchiude tutti i suggerimenti e le convalide e lo colloca sotto l'elemento di input.
numsu,

@ViktorEriksson Se la mia risposta ti è stata utile, ti interessa accettarla?
darksoulsong,

1
Mi dispiace ma non è stato utile, la mia domanda ha ben poco a che fare con quella risposta.
Viktor Eriksson,

Risposte:


28

Sfortunatamente la proiezione del contenuto in campo mat-form non è ancora supportata. Tieni traccia del seguente problema con github per ottenere le ultime notizie al riguardo.

Ormai l'unica soluzione per te è posizionare i tuoi contenuti direttamente nel componente mat-form-field o implementare una classe MatFormFieldControl creando così un componente del campo modulo personalizzato.


133
Mi sono imbattuto in questa domanda cercando su Google un messaggio di errore. La risposta che segue , affermando che è MatInputModulenecessario importare, ha risolto il mio problema. Poiché questa è la risposta accettata, sto aggiungendo il link qui, sperando che salverà il tempo degli altri.
CGFoX,

4
Il mio problema era che avevo trascurato di importare " FormsModule ". Spero che questo aiuti qualcuno.
Lerenau,

@CGFoX Hai assolutamente ragione amico !! l'importazione di MatInputModule ha risolto il mio problema !!
Rafique Mohammed,

5
Anche all'interno di un <mat-form-field>tag devi assicurarti di aver aggiunto correttamente l' matInputattributo su ogni inputtag o l' matNativeControlattributo su ogni<select>
svassr

1
@CGFoX Vorrei che aggiornassero la documentazione con queste informazioni e esempi migliori ...

412

Ho avuto questo problema. Ho importato MatFormFieldModulenel mio modulo principale, ma ho dimenticato di aggiungere MatInputModulel' importsarray, in questo modo:

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

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

Spero che sia d'aiuto.

Maggiori informazioni qui .


9
Anche all'interno di un <mat-form-field>tag devi assicurarti di aver aggiunto correttamente l' matInputattributo su ogni inputtag o l' matNativeControlattributo su ogni <select>tag
svassr

Grazie. Risolto il mio problema Sono nuovo del materiale angolare. Sembra che devo usare molti, molti moduli per usare il materiale angolare. Ad esempio, dobbiamo importare "MatButtonModule" per utilizzare i pulsanti, "MatCheckboxModule" per utilizzare le caselle di controllo, "MatFormFieldModule" per utilizzare i moduli, "MatInputModule" per utilizzare l'input ... È davvero noioso. C'è un modo per importare solo una o due volte e quindi potremmo iniziare a utilizzare il materiale angolare senza ulteriori preoccupazioni?
William Hou,

1
IMPORTANTE: l'ordine è importante!
Becario Senior,

non funziona per me, ho appena usato questo esempio: material.angular.io/components/stepper/overview
tatsu

Questo ha funzionato per me import { MatInputModule } from '@angular/material/input':
Jared Whipple il

86

Soluzione 1: importa MatInputModule

importare il MatInputModulemodulo ieapp.module.ts

Angolare 9+

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

Sotto angolare 9

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

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

Soluzione 2 - Errore ortografico

Assicurati di aggiungere matInputed è sensibile al maiuscolo / minuscolo.

<input matInput type="text" />

2
Ahh, questo mi stava facendo impazzire. Motivo per cui uno ha funzionato per me. Penso che dovrebbe essere specificato nella documentazione, anche se adesso sembra ovvio.
Feign,

Ho riscontrato questo problema quando "matInput" mancava dall'istruzione di input.
HadidAli,

17

Citando dalla documentazione ufficiale qui :

Errore: mat-form-field deve contenere un MatFormFieldControl

Questo errore si verifica quando non è stato aggiunto un controllo campo modulo al campo modulo. Se il campo del modulo contiene un nativo o un elemento, assicurati di aver aggiunto la direttiva matInput e di aver importato MatInputModule. Altri componenti che possono fungere da controllo del campo modulo includono e qualsiasi controllo del campo modulo personalizzato che hai creato.


14

Questo può accadere anche se hai un input appropriato all'interno di un campo mat-form , ma ha un inputngIf . Per esempio:

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

Nel mio caso, mat-chip-listdovrebbe "apparire" solo dopo che i suoi dati sono stati caricati. Tuttavia, la convalida viene eseguita e si mat-form-fieldlamenta

mat-form-field deve contenere un MatFormFieldControl

Per risolverlo, il controllo deve essere lì, quindi ho usato [hidden]:

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

Una soluzione alternativa è proposta da Mosta: move * ngIf per mat-form-field:

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

Ho appena avuto un problema simile, l'ho risolto con qualcosa di simile a quello che stai dicendo. Hai il mio voto!
Alex

3
Grazie, invece di usare nascosto puoi spostare la condizione ngS sull'intero tag mat-form-field
Mosta,

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



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

3
Benvenuto in StackOverflow. Quando rispondi alle domande, aggiungi qualche spiegazione su cosa fa lo snippet di codice e perché risolve la domanda del PO. Per maggiori informazioni controlla qui Come rispondere
Djensen, il

6

Non sono sicuro che possa essere così semplice ma ho avuto lo stesso problema, cambiando "mat-input" in "matInput" nel campo di input ha risolto il problema. Nel tuo caso vedo "matinput" e la mia app genera lo stesso errore.

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

inserisci qui la descrizione dell'immagine

"MatInput"

inserisci qui la descrizione dell'immagine


hmm non sono sicuro, hai incollato l'output generato. Nel vero codice è già matInput, se vedi "textbox-section". Non ho problemi a farlo funzionare solo usando il materiale, è quando provo a rendere il mio compoenent con la proiezione smette di funzionare. Il mio plunker sembra avere problemi, speriamo che si risolva da solo durante il giorno.
Viktor Eriksson,

Oh capisco, mio ​​male. Questa è stata comunque una possibilità. Seguirò per vedere se qualcuno può effettivamente trovare l'angolo di inclinazione corretto, sono curioso di questo problema.
Tabella di ritorno

2
E 'successo con me, ho dimenticato di cambiare mdInputa matInput.
Ebraheem Alrabee "

2
Angolare 5: l'attributo tag <input> dovrebbe essere matInputinvece di mat-input.
Stavm,

6

Se qualcuno si è bloccato con questo errore dopo aver tentato di annidare un <mat-checkbox>, sii di buon umore! Non funziona all'interno di un <mat-form-field>tag.


6

se qualcuno sta cercando di nidificare un <mat-radio-group>dentro <mat-form-field> come un sotto, otterrai questo errore

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

rimuovere i <mat-form-field>tag principali


Stavo avendo questo problema e ho avuto un frammento di markup con questo genere di cose. La rimozione del mat-form-fieldproblema ha risolto il problema.
Andrew Grey,

C'è un motivo che <mat-form-field>non supporta il gruppo radio al suo interno? Stavo riscontrando anche questo problema e non pensavo di rimuovere solo i tag del campo modulo mat perché non sembrava che sarebbe stata la cosa giusta da fare poiché vengono utilizzati così tanti esempi di moduli dell'interfaccia utente dei materiali <mat-form-field>. Ho tutti i vari moduli di input dei moduli per i moduli, selezionare i menu a discesa e i gruppi radio definiti nella mia app.module.ts come molti altri riferimenti di risposte.
Alex

Non posso crederci .... Provo tutto e niente per funzionare .... e dopo alcuni giorni di dolore ho trovato questa soluzione così semplice ... grazie
amico

4

Ho avuto anche questo problema e ho un <mat-select>elemento nel mio modello, quando importare MatSelectModule in Module, funziona, non fa scienza, ma spero che possa aiutarti.

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>

Funziona come senza importare il modulo il controllo campo mat-form non capisce cosa sia un mat-select. Quando viene importato, può sistemare tutte le informazioni e quindi può analizzare il modello senza ulteriori errori.
PeterS,

3

Sfortunatamente non posso solo commentare alcune risposte già buone in quanto non ho ancora i punti SO, tuttavia, ci sono 3 moduli chiave di cui avrai bisogno per assicurarti di importare nel modulo genitore del tuo componente, a parte ciò che devi importare direttamente nel tuo componente. Volevo condividerli brevemente ed evidenziare ciò che fanno.

  1. MatInputModule
  2. MatFormFieldModule
  3. ReactiveFormsModule

I primi due sono per il materiale angolare. Molte persone nuove al materiale angolare si imbatteranno istintivamente in una di queste e non si renderanno conto che la costruzione di una forma richiede entrambe.

Quindi qual è la differenza tra loro?

MatFormFieldModule comprende tutti i diversi tipi di campi modulo disponibili per il materiale angolare. Si tratta più di un modulo di alto livello per i campi modulo in generale, mentre MatInputModule è specifico per i tipi di campo "input", anziché per selezionare caselle, pulsanti di opzione, ecc.

Il terzo elemento dell'elenco sopra è il modulo di forme reattive di Angular. Il modulo di forme reattive è responsabile di una tonnellata di amore angolare nascosto. Se hai intenzione di lavorare con Angular, ti consiglio vivamente di dedicare un po 'di tempo a leggere Angular Docs. Hanno tutte le tue risposte. La creazione di applicazioni raramente NON prevede moduli e, molto spesso, l'applicazione coinvolgerà moduli reattivi. Per questo motivo, ti preghiamo di leggere queste due pagine.

Documenti angolari: forme reattive

Documenti angolari: Modulo di forme reattive

Il primo documento "Forme reattive" sarà la tua arma più potente man mano che inizi, e il secondo documento sarà la tua arma più potente man mano che passerai alle applicazioni più avanzate di Angular Reactive Forms.

Ricorda, questi devono essere importati direttamente nel modulo del tuo componente, non nel componente in cui li stai usando. Se ricordo bene, in Angular 2, abbiamo importato l'intero set di moduli del materiale angolare nel nostro modulo dell'app principale, e quindi importato ciò che dovevamo direttamente in ciascuno dei nostri componenti. Il metodo attuale è molto più efficiente di IMO perché siamo certi di importare l'intero set di moduli di materiale angolare se ne utilizziamo solo alcuni.

Spero che ciò fornisca un po 'più di comprensione sulla costruzione di forme con materiale angolare.


3

Se tutte le principali risposte relative alla struttura / configurazione del codice sopra riportate non risolvono il problema, ecco un'altra cosa da verificare: assicurati di non aver in alcun modo invalidato il <input>tag.

Ad esempio, ho ricevuto lo stesso mat-form-field must contain a MatFormFieldControlmessaggio di errore dopo aver inserito accidentalmente un requiredattributo dopo una barra a chiusura automatica /, che ha effettivamente invalidato il mio <input/>. In altre parole, l'ho fatto (vedere la fine degli attributi del tag di input):

sbagliato :

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

giusto :

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

Se commetti quell'errore o qualcos'altro per invalidare il tuo <input>, allora potresti ottenere l' mat-form-field must contain a MatFormFieldControlerrore. Comunque, questa è solo un'altra cosa da cercare durante il debug.


3

Lo stesso errore può verificarsi se hai una diapositiva di tappetino all'interno di un tappetino dal campo come unico elemento nel mio caso che ho avuto

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

Ciò potrebbe accadere se nella <mat-form-field> soluzione Semplice fossero presenti diversi attributi: spostare la diapositiva sulla radice


1
Questo mi ha salvato la vita. Grazie.
Paulo Pedroso,

2

Puoi provare a seguire questa guida e implementare / fornire il tuo MatFormFieldControl


2

Ho rimosso accidentalmente matInput direttiva dal campo di input che ha causato lo stesso errore.

per esempio.

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

codice fisso

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

2

MatRadioModule non funzionerà all'interno di MatFormField. I documenti dicono

Questo errore si verifica quando non è stato aggiunto un controllo campo modulo al campo modulo. Se il campo del modulo contiene un nativo o un elemento, assicurati di aver aggiunto la direttiva matInput e di aver importato MatInputModule. Altri componenti che possono fungere da controllo del campo modulo includono <mat-select>, <mat-chip-list> e qualsiasi controllo campo modulo personalizzato che hai creato.


2

Nel mio caso, una delle parentesi di chiusura di "onChanges ()" è stata mancata sull'elemento di input e quindi l'elemento di input apparentemente non è stato reso affatto:

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

2

Una soluzione parziale consiste nell'avvolgere il campo del modulo materiale in un componente personalizzato e implementare l' ControlValueAccessorinterfaccia su di esso. Oltre alla proiezione dei contenuti, l'effetto è praticamente lo stesso.

Vedi l'esempio completo su Stackblitz.

Ho usato FormControl( forme reattive ) all'interno CustomInputComponentma FormGroupo FormArraydovrei funzionare anche se hai bisogno di un elemento di forma più complesso.

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

Devi importare MatInputModule nel tuo file app.module.ts

importare {MatInputModule} da '@ 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

Puoi impostare aspect = "fill" all'interno del tuo tag mat-form-field, funziona per me

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

Questo risolto il mio problema. Puoi per favore spiegare cosa ci appearence = "fill"fa qui
IamGrooot il

2

Angolare 9+ ... Materiale 9+

Ho notato che 3 errori possono dare origine allo stesso errore:

  1. Assicurati di aver importato MatFormFieldModule e MatInputModule in app.module o module.ts in cui vengono importati i componenti (nel caso di moduli nidificati)
  2. Quando si avvolgono i pulsanti del materiale o la casella di controllo nel campo modulo opaco. Vedi l'elenco dei componenti del materiale che possono essere avvolti con mat-form-field mat-form-field
  3. Quando non riesci a includere matInput nel tuo tag. cioè <input matInput type = "number" step = "0.01" formControlName = "price" />


1

Nel mio caso ho cambiato questo:

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

a questa:

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

L'aggiunta della direttiva matInput al tag di input è stato ciò che ha risolto questo errore per me.



1

usa i provider nel file component.ts

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

0

Nota Qualche volta si verifica un errore, quando usiamo il tag "campo modulo-mat" attorno al pulsante di invio come:

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

Quindi gentilmente non utilizzare questo tag attorno al pulsante di invio


0

Ho avuto lo stesso problema

il problema è semplice

solo tu devi importare due moduli nel tuo progetto

MatFormFieldModule MatInputModule


0

stavo ottenendo lo stesso problema a causa dell'elemento commentato come segue.

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

il campo modulo dovrebbe avere elemento! (es. input, textarea, select, ecc.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.