Поле mat-form должно содержать MatFormFieldControl

Мы пытаемся создать наши собственные компоненты поля формы в нашей компании. Мы пытаемся обернуть компоненты дизайна материала следующим образом:

поле:

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

Но я получаю "поле mat-form-field должно содержать MatFormFieldControl" в консоли. Я предполагаю, что это связано с полем mat-form-field, не содержащим непосредственно поле matInput. Но он содержит его, он только в проекции ng-контента.

Вот блиц:https://stackblitz.com/edit/angular-xpvwzf

Ответ 1

К сожалению, проекция контента в mat-form-field пока не поддерживается. Пожалуйста, отслеживайте следующую проблему GitHub, чтобы получать последние новости об этом.

К настоящему времени единственное решение для вас - это либо разместить ваш контент непосредственно в компоненте mat-form-field, либо реализовать класс MatFormFieldControl, создав, таким образом, пользовательский компонент поля формы.

Ответ 2

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

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

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

Надеюсь, что это поможет.

Подробнее здесь.

Ответ 3

Решение 1

импортировать MatInputModule внутри app.module.ts

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

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

Решение 2

Обязательно добавьте matInput, и он чувствителен к регистру.

<input matInput type="text" />

Ответ 4

Цитата из официальной документации здесь:

Ошибка: поле mat-form должно содержать MatFormFieldControl

Эта ошибка возникает, если вы не добавили элемент управления поля формы в свою поле формы. Если поле формы содержит элемент, убедитесь, что вы добавили директиву matInput к нему и импортированный MatInputModule. Другие компоненты, которые могут действовать как поле формы контроль включает, и любую пользовательскую форму которые вы создали.

Ответ 5

Это также может произойти, если у вас есть правильный ввод в поле mat-form-field, но на нем есть 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-field должно содержать MatFormFieldControl

Чтобы исправить это, элемент управления должен быть там, поэтому я использовал [hidden]:

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

Альтернативное решение предложенное Mosta: перемещение * ngIf для mat-form-field:

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

Ответ 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"

enter image description here

"matinput"

enter image description here

Ответ 7

Если кто-то застрял с этой ошибкой после попытки вложить <mat-checkbox>, будьте добры! Он не работает внутри <mat-form-field>.

Ответ 8

У меня тоже была эта проблема, и у меня есть элемент <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>

Ответ 9

Вы можете попробовать следовать этому руководству и реализовать/предоставить свой собственный MatFormFieldControl

Ответ 10

Я случайно удалил директиву 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>

Ответ 11

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

  1. MatInputModule
  2. MatFormFieldModule
  3. ReactiveFormsModule

Первые два для углового материала. Многие люди, плохо знакомые с Angular Material, инстинктивно сталкиваются с одним из них и не понимают, что построение формы требует и того, и другого.

Так какая разница между ними?

MatFormFieldModule охватывает все различные типы полей формы, которые доступны в Angular Material. Это в большей степени модуль высокого уровня для полей формы в целом, тогда как MatInputModule специально предназначен для типов полей "ввода", а не для полей выбора, переключателей и т.д.

Третий элемент в приведенном выше списке - модуль угловых реактивных форм. Модуль Reactive Forms отвечает за тонну скрытой любви. Если вы собираетесь работать с Angular, я настоятельно рекомендую вам потратить некоторое время на чтение Angular Docs. У них есть все ваши ответы. Создание приложений редко НЕ включает формы, и чаще всего ваше приложение будет включать в себя реактивные формы. По этой причине, пожалуйста, найдите время, чтобы прочитать эти две страницы.

Angular Docs: Реактивные формы

Angular Docs: модуль реактивных форм

Первый документ "Реактивные формы" станет вашим самым мощным оружием с самого начала, а второй документ станет вашим самым мощным оружием, когда вы перейдете к более сложным приложениям угловых реактивных форм.

Помните, что их нужно импортировать непосредственно в модуль компонента, а не в компонент, в котором вы их используете. Если я правильно помню, в Angular 2 мы импортировали весь набор модулей Angular Material в наш основной модуль приложения, а затем импортировали мы нуждались в каждом из наших компонентов напрямую. Текущий метод намного эффективнее IMO, потому что мы гарантированно импортируем весь набор модулей Angular Material, если будем использовать только несколько из них.

Я надеюсь, что это даст немного больше информации о создании форм с помощью Angular Material.

Ответ 12

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

Например, я получил то же самое mat-form-field must contain a MatFormFieldControl сообщение об ошибке 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 ошибку mat-form-field must contain a MatFormFieldControl. В любом случае, это еще одна вещь, которую нужно искать во время отладки.

Ответ 13

MatRadioModule не будет работать внутри MatFormField. Документы говорят

Эта ошибка возникает, когда вы не добавили элемент управления поля формы в поле формы. Если ваше поле формы содержит нативный или элемент, убедитесь, что вы добавили в него директиву matInput и импортировали MatInputModule. Другие компоненты, которые могут выступать в качестве элемента управления полем формы, включают в себя <mat-select>, <mat-chip-list> и любые пользовательские элементы управления полями формы, которые вы создали.

Ответ 14

В моем случае одна из моих закрывающих скобок для "onChanges()" была пропущена на элементе input, и, таким образом, элемент input, по-видимому, вообще не отображался:

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

Ответ 15

Та же самая ошибка может возникнуть, если в качестве циновки в слайде из поля в качестве поля используется слайд с матом. в моем случае у меня было

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

Это может произойти, если у вас есть несколько атрибутов в <mat-form-field> Простое решение состояло в том, чтобы переместить переключатель слайдов в корень

Ответ 16

В моем случае я изменил это:

<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 к тегу input было тем, что исправило эту ошибку для меня.

Ответ 17

Возможно, вы пропустили импорт MatInputModule