mat-form-field必须包含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-content投影中。

下面是闪电战: https://stackblitz.com/edit/angular-xpvwzf < / p >
582122 次浏览

我不确定它是否可以这么简单,但我有同样的问题,在输入字段中将“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

我有这个问题。我在我的主模块中导入了MatFormFieldModule,但忘记将MatInputModule添加到imports数组中,如下所示:

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


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

更多信息在这里

我也有这个问题,我有<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必须包含MatFormFieldControl

当您没有将表单字段控件添加到表单字段时,将发生此错误。如果您的表单字段包含原生的<input><textarea>元素,请确保已向其添加了matInput指令并导入了MatInputModule。其他可以作为表单字段控件的组件包括<mat-select><mat-chip-list>和任何您已创建的自定义表单字段控件。

了解有关创建“自定义表单字段控件”;在这里的更多信息

在你的模块中导入MatInputModule。Ts文件,它将解决问题。

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

后面的表述是原来的答案。

不幸的是,内容投影到mat-form-field还不支持。 请跟踪以下github的问题以获得有关它的最新消息

到目前为止,唯一的解决方案是将您的内容直接放入mat-form-field组件或实现一个MatFormFieldControl类,从而创建一个自定义的表单字段组件。

问题1:MatInputModule未导入

在模块中导入MatInputModuleMatFormFieldModule,即app.module.ts

import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from "@angular/material/form-field";


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

问题2:matInput -拼写错误/忘记添加

一定要添加matInput,它是区分大小写的。

<mat-form-field>
<input matInput type="text" />
</mat-form-field>

问题3:无效的*ngIf放置

检查你在input标记上没有任何条件在任何情况下都是假的,因为mat-form-field在它里面寻找matInput。相反,将*ngIf放在mat-form-field标签上。

<mat-form-field>
<input matInput *ngIf="someCondition"> // don't add condition here, else add in mat-form-field tag
</mat-form-field>

感谢@William Herrmann指出了这个问题#3

问题4:编译器仍然给出错误

如果angular编译器在修复上述问题后仍然报错,那么你必须尝试重新启动应用程序。

ng serve

如果你有垫表单字段中的正确输入,但上面有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>

你可以尝试遵循这个指南并实现/提供你自己的MatFormFieldControl

在我的例子中,我改变了这个:

<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标记中,为我修复了这个错误。

我不小心从输入字段中删除了< em > matInput < / em >指令,这导致了同样的错误。

如。

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

如果有人在试图嵌套<mat-checkbox>后遇到了这个错误,请高兴起来!它在<mat-form-field>标记中不起作用。

不幸的是,我不能只是评论一些已经很好的答案,因为我还没有SO点,然而,有3个关键模块,你需要确保你导入到你的组件的父模块,除了你必须直接导入到你的组件。我想简单地和大家分享一下,并强调一下他们的工作。

  1. MatInputModule
  2. MatFormFieldModule
  3. ReactiveFormsModule

前两个是针对Angular Material的。很多刚接触Angular Material的人会本能地遇到其中一个,但没有意识到构建表单需要两者兼而有之。

那么它们之间有什么区别呢?

MatFormFieldModule包含了Angular Material中所有可用的不同类型的表单字段。这是一个更高级的模块一般的表单字段,而MatInputModule是专门为“输入”字段类型,而不是选择框,单选按钮等。

上面列表中的第三项是Angular的响应式表单模块。响应式表单模块负责大量Angular的底层工作。如果你打算使用Angular,我强烈建议你花点时间阅读Angular Docs。他们有你所有的答案。构建应用程序很少不涉及表单,而且通常情况下,应用程序将涉及响应式表单。因此,请花点时间阅读这两页。

< a href = " https://angular。Angular Docs: Reactive Forms . io/guide/ Reactive - Forms " rel="nofollow noreferrer">

< a href = " https://angular。io/api/forms/ReactiveFormsModule" rel="nofollow noreferrer">Angular Docs:响应式表单模块 . xml

第一个文档“响应式表单”将是你入门时最有力的武器,第二个文档将是你进入更高级的Angular响应式表单应用时最有力的武器。

请记住,这些需要直接导入到组件的模块中,而不是导入到正在使用它们的组件中。如果我没记错的话,在Angular 2中,我们在主app模块中导入了整个Angular Material模块集,然后直接在每个组件中导入了我们需要的内容。目前的方法在我看来要高效得多,因为如果我们只使用其中的几个模块,我们就可以保证导入整个Angular Material模块集。

我希望这篇文章能让你对Angular Material的构建形式有更多的了解。

如果上面所有的主要代码结构/配置答案都不能解决你的问题,还有一件事要检查:确保你没有以某种方式使你的<input>标记失效。

例如,我意外地将required属性和自关闭斜杠/放在一起后,收到了相同的mat-form-field must contain a MatFormFieldControl错误消息,这有效地使我的<input/>无效。换句话说,我这样做了(参见输入标签属性的末尾):

< em >错误: < / em >

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

< em >正确的: < / em >

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


如果你犯了这个错误或其他使你的<input>无效的错误,那么你会得到mat-form-field must contain a MatFormFieldControl错误。不管怎样,这只是调试时要注意的另一件事。

MatRadioModule将不能在MatFormField中工作。 文档

当您没有将表单字段控件添加到您的控件时,将发生此错误 表单字段。如果您的表单字段包含原生或 元素,确保你已经添加了matInput指令到它 MatInputModule进口。其他可以作为表单字段的组件 控制包括 <mat-select > & lt;Mat-chip-list >,以及任何自定义表单

.字段控件

在我的例子中,输入元素上漏掉了“onChanges()”的一个右括号,因此输入元素显然根本没有被呈现:

<input mat-menu-item
matInput type="text"
[formControl]="myFormControl"
(ngModelChange)="onChanged()>
如果你在一个mat from field中有一个mat slide作为唯一的元素,同样的错误也会发生 在我的例子中,我有

 <mat-form-field>
<mat-slide-toggle [(ngModel)]="myvar">
Some Text
</mat-slide-toggle>
</mat-form-field>
如果你在<mat-form-field>中有几个属性,这可能会发生 简单的解决方案是将滑动开关移动到根

你可能错过了导入MatInputModule

,如果有人试图在<mat-form-field>中嵌套<mat-radio-group> 如下所示,你会得到这个错误

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

部分解决方案是将材质表单字段包装在自定义组件中,并在其上实现ControlValueAccessor接口。除了内容投影之外,效果几乎是一样的。

参见Stackblitz上的完整的示例

我在CustomInputComponent中使用了FormControl (活性形式),但如果你需要更复杂的表单元素,FormGroupFormArray也应该工作。

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>

< >强注 当我们在提交按钮周围使用"mat-form-field"标签时,会出现错误:

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

所以请不要在提交按钮周围使用这个标签

我也有同样的问题

问题很简单

只有两个模块必须导入到项目中

< p > < >强MatFormFieldModule MatInputModule < /强> < / p >
import {MatInputModule} from '@angular/material/input';






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

我得到了同样的问题,由于评论元素如下。

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

表单字段应该有元素!(例如输入,文本区域,选择等)

您在输入标记中错过了matInput指令。

你需要将MatInputModule导入到app.module.ts文件中

import {MatInputModule} from '@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
],

你可以在你的mat-form-field标签中设置appearance="fill",这对我来说很有用

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

在组件中使用提供者。ts文件

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

Angular 9+…材料9 +

我注意到有3个错误会导致同样的错误:

  1. 确保你已经在app.module或模块中导入了MatFormFieldModule和MatInputModule。导入组件的t(嵌套模块的情况下)
  2. 当你包装材料按钮或复选框在垫形式领域。参见可以用mat-form-field mat-form-field包装的材质组件列表
  3. 当你没有在标签中包含matInput时。例如:input matInput type="number"一步=“0.01”;formControlName =“price"/比;

新更新的MatInput模块导入是:

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

根据Angular Materials API

我导入了模块并设置了指令,在再次执行'ng add @angular/material'后,它开始工作了。也许用ng serve重启应用就足够了

我收到了同样的错误消息,但在我的情况下,上述内容都不能解决问题。解决方案在“__abc0”中。你需要添加'mat-label'和把你的输入'label'标签也。我的问题的解决方案是在下面的片段:

  <mat-label>
Username
</mat-label>
<label>
<input
matInput
type="text"
placeholder="Your username"
formControlName="username"/>
</label>

input被错误地放在mat-form-field之外时,也会出现此错误。要修复它,就像下面这样把它带进去:

糟糕的代码:

<mat-form-field class="full-width">
</mat-form-field>
<input matInput placeholder="Title" formControlName="title" #title />

解决办法:

<mat-form-field class="full-width">
<input matInput placeholder="Title" formControlName="title" #title />
</mat-form-field>
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';

不要忘记在<tabe></table>的开头添加

 <mat-form-field>
<mat-label>Filter</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="Ex. Helium" #input>
</mat-form-field>

不要忘记在最后添加<tabe></table>

<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4">
No data matching the filter "\{\{input.value}}"
</td>
</tr>

对我来说,这个错误是由于在<mat-form-field></mat-form-field>中缺少<input>和formControl属性

<form [formGroup]="FormName">
<mat-form-field>
<mat-label>Name</mat-label>
</mat-form-field>
</form>

这是错误的.. 正确的是下面的

<form [formGroup]="FormName">
<mat-form-field>
<mat-label>Name</mat-label>
<input matInput formControlName="name">
</mat-form-field>
</form>

我在一次Karma测试中遇到了问题

正如大多数答案已经指出的那样,缺失的模块会导致问题,它们也必须重新导入到Karma TestBed中。此外,似乎我们还需要导入BrowserAnimationsModule来使一切正常工作。

在我下面的代码中,我注释了一些可能对你没用的模块,但其他4个导入肯定会有帮助!

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ EventFormComponent ],
imports: [
# HttpClientTestingModule,
# RouterTestingModule,
ReactiveFormsModule,
MatFormFieldModule,
MatInputModule,
BrowserAnimationsModule,
# TranslateModule.forRoot(),
],
})
.compileComponents();
}));
只要在每个输入中添加matInput指令,matselect和mat-chip-list enter image description here < / p >

未捕获错误:mat-form-field必须包含MatFormFieldControl。

此错误发生在导入中遗漏'MatInputModule'时,

import { MatInputModule } from '@angular/material/input'
import { MatFormFieldModule } from '@angular/material/form-field'


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

在模块中导入MatInputModule。t文件将有助于摆脱这个问题。

这意味着你没有导入MatInputModule

import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from "@angular/material/form-field";


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

在我的例子中,它是TranslocoService服务,它可能会打乱init之后的初始化。

我的代码是这样的:

<mat-form-field
class="fuse-mat-dense fuse-mat-no-subscript fuse-mat-rounded w-full min-w-50">
<mat-icon
class="icon-size-5"
matPrefix
[svgIcon]="'heroicons_solid:search'"></mat-icon>
<input
*transloco="let t"
(keyup.enter)="searchByCustomerName()"
matInput
[formControl]="searchInputControl"
[autocomplete]="'off'"
placeholder="\{\{t('customer.management.customers.search.customer.name')}}">
</mat-form-field>

我把它改成了这样。

<mat-form-field
class="fuse-mat-dense fuse-mat-no-subscript fuse-mat-rounded w-full min-w-50">
<mat-icon
class="icon-size-5"
matPrefix
[svgIcon]="'heroicons_solid:search'"></mat-icon>
<input
(keyup.enter)="searchByCustomerName()"
matInput
[formControl]="searchInputControl"
[autocomplete]="'off'"
[placeholder]="searchBarPlaceHolder">
</mat-form-field>
占位符值来自Component的一个字段。 经过这种修改,错误就消失了。如果你正在使用transloco,你可以试试这个

如果在mat-form-field下面有输入标记,那么每个输入必须有matInput

每个人都解释了他是如何解决这个问题的,但没有一个答案解决了我的问题,当我发现在做这些答案中解释的所有事情之前,

你必须安装(添加)角材料到你的项目

ng add @angular/material

对我来说,这就是问题的原因。