关于angular:mat-form-field必须包含MatFormFieldControl

mat-form-field must contain a MatFormFieldControl

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

领域:

1
2
3
4
5
6
<mat-form-field>
    <ng-content></ng-content>
    <mat-hint align="start">{{hint}} </mat-hint>
    <mat-hint align="end">{{message.value.length}} / 256</mat-hint>
    <mat-error>This field is required</mat-error>
</mat-form-field>

文本框:

1
2
3
4
5
6
7
8
9
<field hint="hint">
    <input matInput
    [placeholder]="placeholder"
    [value]="value"
    (change)="onChange($event)"
    (keydown)="onKeydown($event)"
    (keyup)="onKeyup($event)"
    (keypress)="onKeypress($event)">
</field>

用法:

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

结果大约是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    <textbox  placeholder="Personnummer/samordningsnummer" value="" ng-reflect-placeholder="Personnummer/samordningsnummer">
       <field>
          <mat-form-field class="mat-input-container mat-form-field>
             
               
                   
                      <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>
                   
               
               
                   <span class="mat-input-ripple mat-form-field-ripple"></span>
               
               
             
          </mat-form-field>
       </field>
    </textbox>

但是我在控制台中收到" mat-form-field必须包含MatFormFieldControl"的信息。 我想这与不直接包含matInput-field的mat-form-field有关。 但是它包含了它,只是带有ng-content投影。

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


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

1
2
3
4
5
6
7
8
9
import { MatFormFieldModule, MatInputModule } from '@angular/material';

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

更多信息在这里。


在这里引用官方文档:

Error: mat-form-field must contain a MatFormFieldControl

This error occurs when you have not added a form field control to your
form field. If your form field contains a native or
element, make sure you've added the matInput directive to it and have
imported MatInputModule. Other components that can act as a form field
control include , , and any custom form
field controls you've created.


如果您在mat-form-field内输入了正确的值,但输入了ngIf,也会发生这种情况。例如。:

1
2
3
4
5
<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 must contain a MatFormFieldControl

要修复它,控件必须在这里,所以我使用了[hidden]

1
2
3
4
5
<mat-form-field>
    <mat-chip-list [hidden]="_dataLoading">
        <!-- other content here -->
    </mat-chip-list>
</mat-form-field>

Mosta提出了另一种解决方案:为mat-form-field移动* ngIf:

1
2
3
4
5
<mat-form-field *ngIf="!_dataLoading">
    <mat-chip-list >
        <!-- other content here -->
    </mat-chip-list>
</mat-form-field>


1
2
3
4
5
6
7
8
9
10
11
12
import {MatInputModule} from '@angular/material/input';



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


如果有人尝试嵌套后遇到此错误,请加油!它在标记内不起作用。


如果有人试图将嵌套在
如下所示,您将收到此错误

1
2
3
4
5
6
7
         <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-input"更改为" matInput"可以解决此问题。在您的情况下,我看到" matinput",这导致我的应用程序抛出相同的错误。

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { MatSelectModule } from '@angular/material/select';

imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatSidenavModule,
    MatButtonModule,
    MatIconModule,
    MatToolbarModule,
    MatFormFieldModule,
    MatProgressSpinnerModule,
    MatInputModule,
    MatCardModule,
    MatSelectModule
],


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


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

例如,我在自动闭合斜线/后不小心放置了required属性,实际上使我的无效之后,收到了相同的mat-form-field must contain a MatFormFieldControl错误消息。换句话说,我做到了(请参见输入标签属性的末尾):

错误:

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

对:

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

如果您犯了该错误或其他使您的无效的错误,则可能会出现mat-form-field must contain a MatFormFieldControl错误。无论如何,这只是调试时要寻找的一件事。


如果您在字段中的垫中有一个垫幻灯片作为唯一元素,则可能会发生相同的错误
就我而言

1
2
3
4
5
 <mat-form-field>
    <mat-slide-toggle [(ngModel)]="myvar">
       Some Text
     </mat-slide-toggle>
 </mat-form-field>

如果您在中具有多个属性,则可能会发生这种情况
简单的解决方案是将幻灯片切换器移到根


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

  • MatInputModule
  • MatFormFieldModule
  • ReactiveForms模块
  • 前两个用于角度材料。很多对Angular Material陌生的人会本能地遇到其中之一,而没有意识到构建表单需要同时使用这两种方法。

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

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

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

    Angular Docs:反应形式

    Angular Docs:反应形式模块

    在开始使用Angular Reactive Forms的更高级应用程序时,第一个文档" Reactive Forms"将是您功能最强大的武器,而第二个文档将是您功能最强大的武器。

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

    我希望这能为使用Angular Material的建筑形式提供更多的见识。


    MatRadioModule无法在MatFormField中使用。
    医生说

    This error occurs when you have not added a form field control to your
    form field. If your form field contains a native or
    element, make sure you've added the matInput directive to it and have
    imported MatInputModule. Other components that can act as a form field
    control include < mat-select>, < mat-chip-list>, and any custom form
    field controls you've created.


    您可以尝试遵循本指南并实现/提供自己的MatFormFieldControl


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

    例如。

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

    固定码

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

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

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

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

    请参阅Stackblitz上的完整示例。

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

    app.component.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <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>

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


    You need to import the MatInputModule into your app.module.ts file

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    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标签内设置外观=" fill",它对我有用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <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>


    角9+ ...材料9+

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

  • 确保已在要导入组件的app.module或module.ts中导入了MatFormFieldModule和MatInputModule(对于嵌套模块)
  • 当您将材料按钮或复选框包装在垫子形式字段中时。请参阅可以用mat-form-field包裹的材料组件列表
  • 当您未能在标签中包含matInput时。即

  • 新更新的MatInput模块导入为:

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

    根据Angular Materials API


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

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

    对此:

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

    将matInput指令添加到输入标签是为我修复了此错误的原因。


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

    1
    2
    3
    4
    5
    6
    7
    8
    @Component({
     selector: 'your-selector',
     templateUrl: 'template.html',
     styleUrls: ['style.css'],
     providers: [
     { provide: MatFormFieldControl, useExisting: FormFieldCustomControlExample }  
    ]
    })

    您可能错过了导入MatInputModule


    我有相同的错误消息,但就我而言,以上均不能解决问题。解决方案在"标签"中。您需要添加" mat-label"并将输入内容也放入" label"标签中。我的问题的解决方案在以下代码段中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      <mat-label>
         Username
      </mat-label>
      <label>
        <input
           matInput
           type="text"
           placeholder="Your username"
           formControlName="username"/>
      </label>

    注意
    一段时间,当我们在"提交"按钮周围使用" mat-form-field"标签时,会发生错误:

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

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


    我有同样的问题

    问题很简单

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

    MatFormFieldModule
    MatInputModule


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

    1
    2
    3
    4
    5
    6
    7
    8
    <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>

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


    我已经导入了模块并设置了指令,执行完" ng add @ angular / material"后,它又开始工作了。也许只要用" ng serve"重新启动应用程序就足够了