поле mat-form повинно містити MatFormFieldControl


187

Ми намагаємося створити власні компоненти-форми-компоненти у нашій компанії. Ми намагаємось обернути такі компоненти дизайну матеріалів, як це:

поле:

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

текстове вікно:

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

Використання:

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

Це призводить приблизно до цього:

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

Але я отримую "мат-форма-поле повинно містити MatFormFieldControl" в консолі. Я думаю, що це стосується мат-форм-поля, яке не містить безпосередньо мат-вхідне поле. Але він містить його, він просто за допомогою проекції вмісту ng.

Ось бліц: https://stackblitz.com/edit/angular-xpvwzf


3
Ви коли-небудь вирішували це питання? У мене точно така ж проблема. Відповіді не стосуються.
нумсу

Ні, на жаль, немає: /. Я знайшов це: github.com/angular/material2/isissue/9411, і якщо я правильно це зрозумів, атм не підтримується.
Віктор Ерікссон

Добре. Дякую, я закінчила створення компонента, який просто завершує всі підказки та перевірки, і помістив його під вхідний елемент.
numsu

@ViktorEriksson Якщо моя відповідь вам була корисною, ви хочете її прийняти?
darksoulsong

1
Вибачте, але це було не корисно, моє запитання дуже мало стосується цієї відповіді.
Віктор Ерікссон

Відповіді:


28

На жаль, проекція вмісту в полі mat-form ще не підтримується. Будь ласка, відстежте наступний випуск github, щоб отримати останні новини про нього.

Наразі єдиним для вас рішенням є або розмістити свій вміст безпосередньо в компоненті mat-form-field, або реалізувати клас MatFormFieldControl, створивши таким чином спеціальний компонент поля форми.


132
Я натрапив на це питання, гуглюючи повідомлення про помилку. Відповідь нижче , вказавши , що MatInputModuleнеобхідно імпортувати вирішити мою проблему. Оскільки це прийнята відповідь, я додаю посилання сюди, сподіваючись, що це заощадить чужий час.
CGFoX

4
Моя проблема полягала в тому, що я нехтував імпортом " FormsModule ". Я сподіваюся, що це комусь допоможе.
lerenau

@CGFoX Ви абсолютно прав чувак !! імпорт MatInputModule вирішив мою проблему !!
Рафік Мухаммед

5
Також усередині <mat-form-field>тегу потрібно переконатися, що ви правильно додали matInputатрибут до кожного inputтегу чи matNativeControlатрибута для кожного<select>
svassr

1
@CGFoX Я б хотів, щоб вони оновлювали документацію з цією інформацією та кращими прикладами ...

410

У мене було це питання. Я імпортував MatFormFieldModuleу свій основний модуль, але забув додати MatInputModuleдо importsмасиву, як-от так:

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

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

Сподіваюся, це допомагає.

Більше інформації тут .


9
Також усередині <mat-form-field>тегу потрібно переконатися, що ви правильно додали matInputатрибут до кожного inputтегу чи matNativeControlатрибута кожного <select>тегу
svassr

Дякую. Вирішив мою проблему. Я новачок у Angular Material. Здається, що мені потрібно імпортувати багато, багато модулів, щоб використовувати кутовий матеріал. Наприклад, нам потрібно імпортувати "MatButtonModule" для використання кнопок, "MatCheckboxModule" для використання прапорців, "MatFormFieldModule" для використання форм, "MatInputModule" для використання вхідних даних ... Це дійсно стомлено. Чи є спосіб імпортувати лише один чи два рази, і тоді ми можемо почати використовувати кутовий матеріал без зайвих турбот?
Вільям Хоу

1
ВАЖЛИВО: Замовлення має значення!
Бекаріо Старший

не працює для мене, я просто використав цей приклад: material.angular.io/components/stepper/overview
tatsu

Це працювало для мене import { MatInputModule } from '@angular/material/input':
Джаред Віппл,

85

Рішення 1 - імпорт MatInputModule

імпорт MatInputModuleвсередині модуля, тобтоapp.module.ts

Кутовий 9+

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

Нижче кутового 9

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

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

Рішення 2 - Помилка правопису

Обов’язково додайте, matInputі це залежно від регістру.

<input matInput type="text" />

2
Ах, це зводило мене з розуму. Причина одна працювала для мене. Я вважаю, що це має бути зазначено в документації, хоча зараз це здається очевидним.
Feign

З цією проблемою я стикався, коли у вхідному операторі відсутній "matInput".
HadidAli

17

Цитування з офіційної документації тут :

Помилка: поле mat-form має містити MatFormFieldControl

Ця помилка виникає, коли ви не додали до поля форми управління полем форми. Якщо поле форми містить власний або елемент, переконайтеся, що ви додали до нього директиву matInput та імпортували MatInputModule. Інші компоненти, які можуть виконувати функції керування полями форм, включають будь-які створені вами власні елементи форми форми.


14

Це також може статися, якщо ви маєте належний вхід у поле mat-form , але воно є ngIfна ньому. Наприклад:

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

У моєму випадку mat-chip-listпередбачається, що "з'явиться" лише після завантаження даних. Однак перевірка виконується і mat-form-fieldподає скарги

поле mat-form повинно містити MatFormFieldControl

Щоб виправити це, контроль повинен бути там, тому я використав [hidden]:

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

Альтернативне рішення пропонується Mosta: move * ngIf для mat-form-field:

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

У мене просто була подібна проблема, я вирішив її чимось схожим на те, що ви говорите. Ви маєте мою позицію!
Олексій

3
Дякую, замість того, щоб використовувати приховані, ви можете перемістити умову ngIf на весь тег mat-form-field
Mosta

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



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

3
Ласкаво просимо в stackoverflow. Відповідаючи на запитання, будь ласка, додайте пояснення щодо того, що робить ваш фрагмент коду та чому він вирішує питання ОП. Для отримання додаткової інформації дивіться тут Як відповісти
Djensen

6

Я не впевнений, чи може це бути просто, але у мене була та сама проблема, змінивши "mat-input" на "matInput" у полі введення, вирішив проблему. У вашому випадку я бачу "matinput", і це призводить до того, що мій додаток кидає ту саму помилку.

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

введіть тут опис зображення


хм не впевнений, ви вставили згенерований результат. У реальному коді це вже matInput, якщо ви бачите "текстовий розділ". У мене немає проблем змусити його працювати, коли просто використовую матеріал, його, коли я намагаюся зробити власний композитор проекцією, він перестає працювати. Здається, у мого викрадача проблеми з атм, сподіваємось, він виправиться протягом дня.
Віктор Ерікссон

Ой бачу, моє погано. Це все одно було давно. Я прослідкую, щоб хтось насправді придумав правильний худий кут, мені цікаво це питання.
ReturnTable

2
Це трапилося зі мною, я забув зміни mdInputдо matInput.
Ebraheem Alrabee '26

2
Кутовий 5: атрибут тегу <input> повинен бути matInputзамість mat-input.
Ставм

6

Якщо хтось застряг у цій помилці після спроби вкласти гніздо <mat-checkbox>, будьте веселі! Він не працює всередині <mat-form-field>тегу.


6

якщо хтось намагається вкласти <mat-radio-group>всередину, <mat-form-field> як нижче, ви отримаєте цю помилку

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

видаліть батьківські <mat-form-field>теги


У мене виникло це питання, і був фрагмент розмітки з подібними речами. Видалення mat-form-fieldзробленої проблеми від мене піде.
Ендрю Грей

Чи є причина, <mat-form-field>яка не підтримує радіогрупу всередині неї? У мене виникло і це питання, і я не думав просто видаляти теги поля матової форми, тому що це не здавалося, що це було б належним чином робити, оскільки так багато прикладів форм користувальницького інтерфейсу використовуються <mat-form-field>. У мене є всі різні модулі введення матеріалів для форм, виберіть спадні меню та радіогрупи, визначені в моєму app.module.ts, як і багато інших посилань на відповіді.
Олексій

Я не можу повірити .... я намагаюся все, і нічого не виходить .... і через кілька днів болю я знайшов це таке просте рішення ... дякую товарише
Артер

4

У мене була і ця проблема, і я маю <mat-select>елемент свого шаблону, коли я імпортую MatSelectModule в модуль, він працює, він не робить наукою, але, сподіваючись, він може вам допомогти.

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>

Він працює так, як без імпорту модуля управління mat-form-field не розуміє, що таке mat-select. Коли він імпортується, він може зафіксувати всю інформацію, а тому може проаналізувати шаблон без додаткової помилки.
PeterS

3

На жаль, я не можу просто прокоментувати деякі вже хороші відповіді, оскільки у мене поки немає точок SO, однак є 3 ключові модулі, які вам знадобляться, щоб переконатися, що ви імпортуєте в батьківський модуль вашого компонента, окрім того вам доведеться імпортувати безпосередньо у свій компонент. Я хотів коротко поділитися ними та висвітлити те, що вони роблять.

  1. MatInputModule
  2. MatFormFieldModule
  3. ReactiveFormsModule

Перші два - для кутового матеріалу. Дуже багато людей, які знайомі з кутовим матеріалом, інстинктивно натраплять на один із них і не усвідомлюють, що побудова форми вимагає обох.

То яка різниця між ними?

MatFormFieldModule охоплює всі типи полів форми, які доступні у Angular Material. Це більше модуль високого рівня для полів форми в цілому, тоді як MatInputModule призначений спеціально для типів полів «введення», на відміну від вибраних вікон, радіо кнопок тощо.

Третій пункт у наведеному вище списку - модуль реагуючих форм Angular. Модуль "Реактивні форми" несе відповідальність за кучу закоханих закоханих. Якщо ви збираєтеся працювати з Angular, я настійно рекомендую вам провести деякий час, читаючи Angular Docs. У них є всі ваші відповіді. У програмах для складання рідко НЕ залучаються форми, і частіше за все ваша програма передбачає реактивні форми. З цієї причини, будь ласка, знайдіть час, щоб прочитати ці дві сторінки.

Кутові документи: реактивні форми

Кутові документи: Модуль реактивних форм

Перший документ "Реактивні форми" стане вашою найпотужнішою зброєю, коли ви розпочнете роботу, а другий документ буде вашою найпотужнішою зброєю, коли ви переходите до більш досконалих застосувань кутових реактивних форм.

Пам'ятайте, що їх потрібно імпортувати безпосередньо в модуль вашого компонента, а не в компонент, яким ви їх використовуєте. Якщо я добре пам’ятаю, у Angular 2 ми імпортували весь набір модулів Angular Material в наш головний модуль програми, а потім імпортували те, що нам потрібно було безпосередньо в кожному з наших компонентів. Нинішній метод є набагато ефективнішим IMO, оскільки ми гарантуємо імпорт всього набору модулів Angular Material, якщо ми будемо використовувати лише декілька з них.

Я сподіваюся, що це дає трохи більше розуміння будівельних форм з кутовим матеріалом.


3

Якщо всі основні відповіді на структуру коду / конфігурації вище не вирішують вашу проблему, ось ще одна річ, щоб перевірити: переконайтеся, що ви якось не визнали свою недійсною <input> тегу .

Наприклад, я отримав те саме mat-form-field must contain a MatFormFieldControlповідомлення про помилку після випадкового введення requiredатрибуту після косої частини /, що закривається , що фактично визнало мою недійсною <input/>. Іншими словами, я зробив це (див. Кінець атрибутів тегу введення):

неправильно :

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

правильно :

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

Якщо ви зробите цю помилку чи щось інше, щоб визнати свою недійсною <input>, ви можете отримати mat-form-field must contain a MatFormFieldControlпомилку. У будь-якому випадку, це лише ще одна річ, на яку потрібно звернути увагу під час налагодження.


3

Така ж помилка може виникнути, якщо у вас є слайд килима в килимку з поля, як єдиний елемент в моєму випадку, у мене був

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

Це може статися, якщо у вас було декілька атрибутів у <mat-form-field> простому рішенні - перенести перемикач слайда до кореня


1
Це врятувало мені життя. Дякую.
Пауло Педросо


2

Я випадково видалив matInput директиву із поля введення, що спричинило ту саму помилку.

напр.

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

фіксований код

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

2

MatRadioModule не працюватиме в MatFormField. У документах говорять

Ця помилка виникає, коли ви не додали до поля форми управління полем форми. Якщо поле форми містить власний або елемент, переконайтеся, що ви додали до нього директиву matInput та імпортували MatInputModule. Інші компоненти, які можуть виконувати функції керування полями форми, включають <mat-select>, <mat-chip-list> та будь-які створені вами власні елементи форми форми.


2

У моєму випадку одна з моїх закритих дужок для "onChanges ()" була пропущена на вхідному елементі, і, таким чином, вхідний елемент, мабуть, взагалі не виводився:

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

2

Часткове рішення полягає в тому, щоб загортати поле матеріального матеріалу в спеціальний компонент і реалізовувати ControlValueAccessorна ньому інтерфейс. Крім прогнозування вмісту, ефект майже однаковий.

Дивіться повний приклад на Stackblitz.

Я використовував FormControl( реактивні форми ) всередині, CustomInputComponentале FormGroupабоFormArray повинен працювати також , якщо вам потрібен більш складний елемент форми.

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

Вам потрібно імпортувати MatInputModule у файл app.module.ts

імпорт {MatInputModule} з '@ 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

Ви можете встановити izgled = "fill" всередині тегу mat-form-field, він працює для мене

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

Це вирішило мою проблему. Поясніть, будь ласка, що appearence = "fill"тут
робиться

2

Кутовий 9+ ... Матеріал 9+

Я помітив, що 3 помилки можуть призвести до тієї ж помилки:

  1. Переконайтесь, що ви імпортували MatFormFieldModule та MatInputModule в app.module або module.ts, куди імпортуються ваші компоненти (у разі вкладених модулів)
  2. Коли ви загортаєте кнопочки матеріалів або прапорець у полі-мат-форму. Див. Перелік компонентів матеріалу, які можна обгорнути мат-формою-полем мат-форма-поле
  3. Якщо ви не можете включити matInput у свій тег. тобто <input matInput type = "number" step = "0.01" formControlName = "ціна" />

1

У моєму випадку я змінив це:

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

до цього:

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

Додавання директиви matInput до тегу вводу було тим, що для мене виправило цю помилку.



1

використовувати провайдерів у файлі компонент.ts

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


0

Примітка Певний час виникає помилка, коли ми використовуємо тег "mat-form-field" навколо кнопки "submit", наприклад:

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

Тому люб'язно не використовуйте цей тег навколо кнопки "Надіслати"


0

У мене було таке ж питання

питання простий

тільки ви повинні імпортувати два модулі до свого проекту

MatFormFieldModule MatInputModule


0

я отримував ту саму проблему завдяки коментованому елементу наступним чином.

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

поле форми повинно мати елемент! (наприклад, введення, текстова область, вибір тощо)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.