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

190

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

поле:

<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. Но он содержит его, он просто проецирует нг-контент.

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

Виктор Эрикссон
источник
3
Вы когда-нибудь решали проблему? У меня точно такая же проблема. Ответы не актуальны.
18:30
Нет, к сожалению нет :/. Я нашел это: github.com/angular/material2/issues/9411 и, если я правильно понимаю, это не поддерживается банкомат.
Виктор Эрикссон
Хорошо. Спасибо, я закончил тем, что создал компонент, который просто обернул все подсказки и проверки и поместил его под элемент input.
Numsu
@ViktorEriksson Если мой ответ был вам полезен, вы принимаете его?
darksoulsong
1
Извините, но это было бесполезно, мой вопрос имеет мало общего с этим ответом.
Виктор Эрикссон,

Ответы:

28

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

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

n.yakovenko
источник
133
Я наткнулся на этот вопрос, погуглив сообщение об ошибке. Ответ ниже , указав , что MatInputModuleнеобходимо импортировать решить мою проблему. Поскольку это принятый ответ, я добавляю сюда ссылку, надеясь, что это сэкономит чужое время.
CGFoX
4
Моя проблема заключалась в том, что я забыл импортировать « FormsModule ». Я надеюсь, что это поможет кому-то.
Леренау
@ CGFoX Ты абсолютно прав чувак !! импорт MatInputModule решил мою проблему !!
Рафике Мухаммед
5
Также внутри <mat-form-field>тега вы должны убедиться, что вы правильно добавили matInputатрибут для каждого inputтега или или matNativeControlатрибута для каждого<select>
svassr
1
@CGFoX Я хотел бы, чтобы они обновили документацию этой информацией и лучшими примерами ...
413

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

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

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

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

Больше информации здесь .

darksoulsong
источник
9
Также внутри <mat-form-field>тега вы должны убедиться, что вы правильно добавили matInputатрибут для каждого inputтега или или matNativeControlатрибута для каждого <select>тега
svassr
Спасибо. Решил мою проблему. Я новичок в Angular Material. Кажется, мне нужно импортировать много-много модулей, чтобы использовать Angular Material. Например, нам нужно импортировать «MatButtonModule» для использования кнопок, «MatCheckboxModule» для использования флажков, «MatFormFieldModule» для использования форм, «MatInputModule» для ввода ... Это действительно утомительно. Есть ли способ импортировать только один или два раза, и тогда мы сможем начать использовать Angular Material, не беспокоясь больше?
Уильям Хоу
1
ВАЖНО: заказ имеет значение!
Бекарио Старший
у меня не работает, я просто использовал этот пример: material.angular.io/components/stepper/overview
tatsu
Это сработало для меня import { MatInputModule } from '@angular/material/input':
Джаред Уиппл
86

Решение 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" />
Wasif
источник
2
Ааа, это сводило меня с ума. Причина первая сработала для меня. Я чувствую, что это должно быть указано в документации, хотя сейчас это кажется очевидным.
Притвориться
Я столкнулся с этой проблемой, когда «matInput» отсутствовал в операторе ввода.
Хадидали Али
17

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

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

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

user158
источник
14

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

<mat-form-field *ngIf="!_dataLoading">
    <mat-chip-list >
        <!-- other content here -->
    </mat-chip-list>
</mat-form-field>
Алексей
источник
У меня просто была похожая проблема, я исправил что-то похожее на то, что вы говорите. У тебя есть мой голос!
Алекс
3
Спасибо, вместо того , чтобы использовать скрытое вы можете переместить состояние ngIf на всем мат-форм-метки поля
Мост
9
import {MatInputModule} from '@angular/material/input';



@NgModule({
    imports: [
        MatInputModule
    ],
    exports: [
        MatInputModule
    ]
})
Иб Абайоми Алли
источник
3
Добро пожаловать в stackoverflow. Отвечая на вопросы, добавьте пояснения относительно того, что делает ваш фрагмент кода и почему он решает вопрос OP. Для получения дополнительной информации проверьте здесь Как ответить
Дженсен
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"

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

ReturnTable
источник
хм не уверен, вы вставили сгенерированный вывод. В реальном коде это уже matInput, если вы видите «textbox-section». У меня нет проблем с тем, чтобы заставить его работать, когда просто использую материал, при попытке сделать свою собственную составляющую с проекцией он перестает работать. У моего плункера, похоже, проблемы с атм, надеюсь, он исправится в течение дня.
Виктор Эрикссон
О, я вижу, мой плохой. Это был длинный выстрел в любом случае. Я пойду, чтобы узнать, может ли кто-нибудь на самом деле придумать правильный угол наклона, мне интересно об этой проблеме.
ReturnTable
2
Это случилось со мной, я забыл изменения mdInputк matInput.
Эбрахим Алраби '26
2
Угловой 5: атрибут тега <input> должен быть matInputвместо mat-input.
Ставм
6

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

Mina
источник
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>
user9001817
источник
Это работает, так как без импорта модуля элемент управления mat-form-field не понимает, что такое mat-select. Когда он импортирован, он может исправить всю информацию и, следовательно, может проанализировать шаблон без дальнейшей ошибки.
PeterS
3

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

  1. MatInputModule
  2. MatFormFieldModule
  3. ReactiveFormsModule

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

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

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

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

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

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

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

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

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

anothercoder
источник
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ошибку. В любом случае, это еще одна вещь, которую нужно искать во время отладки.

CJN
источник
3

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

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

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

Kisinga
источник
1
Это спасло мою жизнь. Спасибо.
Пауло Педросо
2

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

rivanov
источник
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> и любые пользовательские элементы управления полями формы, которые вы создали.

intotecho
источник
2

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

<input mat-menu-item 
      matInput type="text" 
      [formControl]="myFormControl"
      (ngModelChange)="onChanged()>
Java-addict301
источник
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>

заказ 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>
CSG
источник
2

Вы пропустили matInput директиву в своем входном теге.

Исаак Питва
источник
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

Вы можете установить внешний вид = «заполнить» внутри тега 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>
Pawan Singare
источник
Это исправило мою проблему. Не могли бы вы объяснить, что appearence = "fill"здесь происходит
IamGrooot
2

Угловой 9+ ... Материал 9+

Я заметил, что 3 ошибки могут привести к одной и той же ошибке:

  1. Убедитесь, что вы импортировали MatFormFieldModule и MatInputModule в app.module или module.ts, куда импортируются ваши компоненты (в случае вложенных модулей)
  2. Когда вы оборачиваете кнопки материала или флажок в поле mat-form-field. Смотрите список компонентов материала, которые можно обернуть с помощью mat-form-field mat-form-field
  3. Когда вы не можете включить matInput в свой тег. т.е. <input matInput type = "number" step = "0.01" formControlName = "price" />
7guyo
источник
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 к тегу input было тем, что исправило эту ошибку для меня.

Gilmourguru
источник
1

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

Пранит Багган
источник
1

использовать провайдеров в файле component.ts

@Component({
 selector: 'your-selector',
 templateUrl: 'template.html',
 styleUrls: ['style.css'],
 providers: [
 { provide: MatFormFieldControl, useExisting: FormFieldCustomControlExample }   
]
})
Bimzee
источник
0

Примечание. Иногда возникает ошибка, когда мы используем тег «mat-form-field» вокруг кнопки отправки, например:

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

поле формы должно иметь элемент! (например, ввод, текстовое поле, выделение и т. д.)

U_R_Naveen UR_Naveen
источник