mat-form-field必须包含MatFormFieldControl


180

我们正在尝试在我们的公司构建自己的表单域组件。我们试图像这样包装材料设计的组件:

领域:

<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”的信息。我想这与不直接包含matInput-field的mat-form-field有关。但是它包含了它,只是带有ng-content投影。

这是闪电战:https : //stackblitz.com/edit/angular-xpvwzf


3
您是否解决了这个问题?我有完全相同的问题。答案无关紧要。
numsu

不,很不幸不是:/。我发现了这一点:github.com/angular/material2/issues/9411,如果我正确理解这一点,这是不受支持的atm。
维克多·埃里克森

好的,谢谢。我最终制作了一个仅包装所有提示和验证并将其放在输入元素下的组件。
numsu

@ViktorEriksson如果我的回答对您有用,您是否愿意接受它?
darksoulsong

1
抱歉,它没有用,我的问题与答案几乎没有关系。
维克多·埃里克森

Answers:


25

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

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


130
我在搜寻错误消息时遇到了这个问题。下面答案,指出MatInputModule需要导入解决了我的问题。由于这是可接受的答案,因此我在此处添加链接,希望它可以节省其他人的时间。
CGFoX

3
我的问题是我忽略了导入“ FormsModule ”。我希望这可以帮助别人。
lerenau

@CGFoX你绝对是对的家伙!导入MatInputModule解决了我的问题!
拉菲克·穆罕默德

5
另外一个里面<mat-form-field>你必须确保你的标签添加正确matInput的每个属性input标签或或matNativeControl对每一个属性<select>
svassr

1
@CGFoX我希望他们会使用此信息和更好的示例来更新文档……

407

我有这个问题。我MatFormFieldModule在主模块上导入了,但是忘了添加MatInputModuleimports数组中,如下所示:

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

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

希望能帮助到你。

更多信息在这里


9
同样在<mat-form-field>标签内,您必须确保matInput在每个input标签上正确添加了属性,或matNativeControl在每个<select>标签上添加了属性
svassr

谢谢。解决了我的问题。我是Angular Material的新手。似乎我需要导入很多模块才能使用Angular Material。例如,我们需要导入“ MatButtonModule”以使用按钮,导入“ MatCheckboxModule”以使用复选框,导入“ MatFormFieldModule”以使用表单,导入“ MatInputModule”以使用输入...确实很累。有没有一种方法可以只导入一次或两次,然后我们就可以开始使用Angular Material,而无需再担心了?
侯侯

1
重要提示:订单很重要!
Becario Senior

不适用于我,我只使用了以下示例:material.angular.io/components/stepper/overview
tatsu

这对我 import { MatInputModule } from '@angular/material/input':
有用

82

解决方案1-导入MatInputModule

导入MatInputModule模块内部即app.module.ts

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

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

解决方案2-拼写错误

确保添加matInput,并且区分大小写。

<input matInput type="text" />

2
啊,这让我发疯了。原因一为我工作。我觉得应该在文档中指定它,即使现在看起来很明显。

当输入语句中缺少“ matInput”时,我遇到了此问题。
HadidAli

15

在这里引用官方文档:

错误:mat-form-field必须包含MatFormFieldControl

当您尚未向窗体字段添加窗体字段控件时,会发生此错误。如果您的表单字段包含本机或元素,请确保已向其添加matInput指令并导入了MatInputModule。可以用作表单字段控件的其他组件包括,和您创建的任何自定义表单字段控件。


13

如果您在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>

我只是有一个类似的问题,我用您所说的类似的方法解决了这个问题。你有我的支持!
亚历克斯

3
谢谢,而不是使用隐藏,您可以在整个mat-form-field标签上移动ngIf条件
Mosta

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



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

3
欢迎来到stackoverflow。在回答问题时,请添加一些解释,说明您的代码段的作用以及为什么它可以解决OP的问题。有关更多信息,请
单击

5

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

在此处输入图片说明


不确定,您已粘贴了生成的输出。在实际代码中,如果您看到“ textbox-section”,它已经是matInput。我只使用材质就可以使它正常工作,而当尝试使自己的投影组件停止工作时,它没有问题。我的pl夫似乎在atm上遇到了问题,希望它会在白天修复。
维克多·埃里克森

哦,我明白了,我的坏。无论如何,这是一个远射。我将跟踪看看是否有人真的可以提出正确的倾斜角度,我对此问题很好奇。
ReturnTable

2
它发生在我身上,我忘记了更改mdInputmatInput
Ebraheem Alrabee'17

2
角度5:<input>标签属性应matInput改为mat-input
Stavm '17

5

如果有人尝试嵌套a <mat-checkbox>后仍然遇到此错误,请加油!它在<mat-form-field>标签内不起作用。


5

如果有人试图<mat-radio-group><mat-form-field> 下面嵌套一个like,您将收到此错误

         <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表单字段标签,因为由于使用了许多UI表单示例材料,因此似乎不应该这样做<mat-form-field>。我有许多用于表单的各种材料表单输入模块,可以像其他许多答案参考一样在app.module.ts中定义下拉列表和单选组。
Alex

我不敢相信...。我竭尽所能,没有任何工作....经过几天的痛苦,我发现了这个简单的解决方案...谢谢队友
阿尔特,

2

我也遇到了这个问题,并且<mat-select>我的模板中有元素,当我将MatSelectModule导入Module时,它可以工作,虽然没有科学依据,但仍然希望它能为您提供帮助。

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

2

不幸的是,由于我还没有SO点,所以我不能仅对一些已经很好的答案发表评论,但是,除了3个主要模块之外,您还需要确保要导入到组件的父模块中的3个关键模块您必须直接导入到组件中。我想简要分享一下它们,并强调它们的作用。

  1. MatInputModule
  2. MatFormFieldModule
  3. ReactiveForms模块

前两个用于角度材料。许多不熟悉Angular Material的人会本能地遇到其中之一,而没有意识到构建表格需要同时使用这两种方法。

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

MatFormFieldModule包含Angular Material提供的所有不同类型的表单字段。通常,这更多是用于表单字段的高级模块,而MatInputModule专门用于“输入”字段类型,与选择框,单选按钮等相反。

上面列表中的第三项是Angular的反应形式模块。反应形式模块负责大量的引擎盖下的Angular爱。如果要使用Angular,我强烈建议您花一些时间阅读Angular Docs。他们有您的所有答案。构建应用程序很少不涉及表格,而且您的应用程序经常涉及反应式表格。因此,请花时间阅读这两页。

Angular Docs:反应形式

Angular Docs:反应形式模块

当您入门时,第一个文档“ Reactive Forms”将是您功能最强大的武器,而当您进入Angular Reactive Forms的更高级应用程序时,第二个文档将是您功能最强大的武器。

记住,这些需要直接导入到您组件的模块中,而不是您正在使用它们的组件中。如果我没记错的话,在Angular 2中,我们将整个Angular Material模块集导入了我们的主app模块,然后导入了我们直接需要每个组件。当前的方法使IMO效率更高,因为如果仅使用少数几个角材料模块,则可以保证导入它们。

我希望这可以为使用Angular Material建立表单提供更多的见识。


2

如果以上所有主要代码结构/配置答案都不能解决您的问题,则还需要检查一件事:确保您没有以某种方式使<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错误,则可能会收到该错误。无论如何,这只是调试时要寻找的一件事。


2

如果在我的情况下,只有字段中的垫子中的垫子幻灯片是我遇到的唯一元素,则可能会发生相同的错误

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

如果您在“ <mat-form-field> 简单”解决方案中有多个属性是将幻灯片切换开关移动到根目录,则可能会发生这种情况


1
这救了我一命。谢谢。
Paulo Pedroso,


1

我不小心从输入字段中删除了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>

1

MatRadioModule无法在MatFormField中使用。该文件说,

当您尚未向窗体字段添加窗体字段控件时,会发生此错误。如果您的表单字段包含本机或元素,请确保已向其添加matInput指令并导入了MatInputModule。可以用作表单域控件的其他组件包括 <mat-select>,<mat-chip-list>以及您创建的任何自定义表单域控件。


1

在我的情况下,在输入元素上遗漏了“ onChanges()”的圆括号之一,因此显然根本没有呈现输入元素:

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

1

一种解决方案是将材料表单字段包装在自定义组件中并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>


1

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

从'@ angular / material'导入{MatInputModule};

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

1

角9+ ...材料9+

我注意到3个错误可能会引起相同的错误:

  1. 确保已在要导入组件的app.module或module.ts中导入了MatFormFieldModule和MatInputModule(对于嵌套模块)
  2. 当您将材料按钮或复选框包装在垫子形式字段中时。看到可与垫外形字段被包装材料的组件的列表垫外形场
  3. 当您未能在标签中包含matInput时。即<input matInput type =“ number” step =“ 0.01” formControlName =“ price” />

0

就我而言,我对此进行了更改:

<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指令添加到输入标签是为我修复了此错误的原因。



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

您可以在mat-form-field标签内设置外观=“ 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>

0

在component.ts文件中使用提供程序

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


-1

我有同样的问题

问题很简单

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

MatFormFieldModule MatInputModule


-1

由于注释元素,我遇到了相同的问题,如下所示。

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.