【问题标题】:mat-form-field must contain a MatFormFieldControlmat-form-field 必须包含一个 MatFormFieldControl
【发布时间】:2018-03-24 03:00:23
【问题描述】:

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

字段:

<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 must contain a MatFormFieldControl" 在控制台中。我想这与不直接包含 matInput-field 的 mat-form-field 有关。但它包含它,它只是带有 ng-content 投影。

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

【问题讨论】:

  • 您解决了这个问题吗?我有完全相同的问题。答案不相关。
  • 不,不幸的是:/。我发现了这个:github.com/angular/material2/issues/9411,如果我理解正确,这是不支持的 atm。
  • 好的.. 谢谢,我最终制作了一个组件,它只包含所有提示和验证并将其放在输入元素下。
  • 很抱歉,它没有用,我的问题与那个答案几乎没有关系。
  • 我的情况,我在 标签中使用了 *ngIf。将 if 条件移到 解决了我的问题。

标签: angular typescript angular-material2


【解决方案1】:

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

【讨论】:

  • 嗯不确定,您已粘贴生成的输出。如果您看到“文本框部分”,在实际代码中它已经是 matInput。仅使用材料时我没有问题让它工作,当我试图用投影制作我自己的组件时它停止工作。我的 plunker 似乎有问题 atm,希望它会在白天自行修复。
  • 哦,我明白了,我的错。无论如何,这是一个很长的镜头。我会跟着看看是否有人真的能想出正确的倾斜角度,我很好奇这个问题。
  • 发生在我身上,忘记把mdInput改成matInput了。
  • Angular 5: 标签属性应该是matInput 而不是mat-input
【解决方案2】:

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

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

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

更多信息here.

【讨论】:

【解决方案3】:

我也遇到了这个问题,我的模板中有&lt;mat-select&gt; 元素,当我将 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 控件不了解 mat-select 是什么。导入后,它可以修复所有信息,因此可以解析模板而不会出现进一步的错误。
【解决方案4】:

引用官方文档here

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

当您没有向表单域添加表单域控件时会发生此错误。如果您的表单字段包含原生 &lt;input&gt;&lt;textarea&gt; 元素,请确保您已向其中添加 matInput 指令并已导入 MatInputModule。其他可以充当表单域控件的组件包括&lt;mat-select&gt;&lt;mat-chip-list&gt;,以及您创建的任何自定义表单域控件。

了解更多关于creating a "custom form field control" here

【讨论】:

    【解决方案5】:

    在你的 module.ts 文件中导入 MatInputModule 即可解决问题。

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

    后面的语句是旧答案。

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

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

    【讨论】:

    • 我在谷歌搜索错误消息时遇到了这个问题。 answer below,指出需要导入MatInputModule 解决了我的问题。由于这是公认的答案,因此我在此处添加链接,希望它能节省其他人的时间。
    • 我的问题是我忽略了导入“FormsModule”。我希望这对某人有所帮助。
    • @CGFoX 你是对的,伙计!!导入 MatInputModule 解决了我的问题!!
    • 同样在&lt;mat-form-field&gt;标签内,您必须确保在每个input标签上正确添加matInput属性或在每个matNativeControl属性上添加&lt;select&gt;
    • @CGFoX 我希望他们能用这些信息和更好的例子更新文档......
    【解决方案6】:

    问题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:编译器仍然报 ERROR

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

    ng serve
    

    【讨论】:

    • 啊,这让我发疯了。原因一对我有用。我觉得应该在文档中指定,即使现在看起来很明显。
    • 问题 3. 必须重新启动。谢谢!
    • 在我的情况下是问题 1 和问题 3 :) 我们应该记住在导入新模块后重新启动应用程序。
    • 我遇到了问题 2,我从来没有觉得自己像个白痴。谢谢!:))
    • 正是我的问题没有插入'matInput'。 :'( tks
    【解决方案7】:

    如果您在 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 for mat-form-field:

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

    【讨论】:

    • 谢谢,您可以在整个 mat-form-field 标签上移动 ngIf 条件,而不是使用 hidden
    • ngSwitch 也会发生同样的事情
    • 这是我的问题。解决方案可以挽救生命。
    【解决方案8】:

    您可以尝试遵循此guide 并实施/提供您自己的 MatFormFieldControl

    【讨论】:

      【解决方案9】:

      就我而言,我改变了这个:

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

      【讨论】:

        【解决方案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>
        

        【讨论】:

        • textarea 组件也是必需的,对我来说就是这种情况。
        【解决方案11】:

        如果有人在尝试嵌套 &lt;mat-checkbox&gt; 后遇到此错误,请放心!它在 &lt;mat-form-field&gt; 标记内不起作用。

        【讨论】:

        【解决方案12】:

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

        1. MatInputModule
        2. MatFormFieldModule
        3. 反应式表单模块

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

        那么它们有什么区别呢?

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

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

        Angular Docs: Reactive Forms

        Angular Docs: Reactive Forms Module

        第一个文档“反应式表单”将是您开始时最强大的武器,而第二个文档将是您开始使用更高级的 Angular 反应式表单应用程序时最强大的武器。

        请记住,这些需要直接导入到您的组件模块中,而不是您正在使用它们的组件中。如果我没记错的话,在 Angular 2 中,我们在主应用程序模块中导入了整套 Angular Material 模块,并且然后直接在每个组件中导入我们需要的东西。当前的方法在 IMO 上效率更高,因为如果我们只使用其中的几个,我们就可以保证导入整套 Angular Material 模块。

        我希望这能让您更深入地了解使用 Angular Material 构建表单。

        【讨论】:

          【解决方案13】:

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

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

          错误

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

          正确

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

          如果您犯了该错误或其他错误导致您的&lt;input&gt; 无效,那么您可能会收到mat-form-field must contain a MatFormFieldControl 错误。无论如何,这只是您在调试时要寻找的另一件事。

          【讨论】:

          • 显然,如果您没有正确的结束标签,也会发生这种情况。 &lt;input matInput placeholder="Placeholder"&gt; 无效,但 &lt;input matInput placeholder="Placeholder" /&gt; 有效。
          • 又一个不知名的英雄,谢谢你拯救了我的一天! :)))))))
          【解决方案14】:

          MatRadioModule 不能在 MatFormField 中工作。 docs

          当您没有将表单域控件添加到您的 表单域。如果您的表单域包含原生或 元素,请确保您已将 matInput 指令添加到它并具有 导入 MatInputModule。 其他可以作为表单域的组件 控件包括 和任何自定义表格 您创建的字段控件。

          【讨论】:

            【解决方案15】:

            在我的情况下,输入元素上缺少“onChanges()”的右括号之一,因此输入元素显然根本没有被渲染:

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

            【讨论】:

              【解决方案16】:

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

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

              如果您在 &lt;mat-form-field&gt; 中有多个属性,则可能会发生这种情况 简单的解决方案是将滑动切换移动到根目录

              【讨论】:

                【解决方案17】:

                您可能错过了导入 MatInputModule

                【讨论】:

                  【解决方案18】:

                  如果有人试图将&lt;mat-radio-group&gt; 嵌套在&lt;mat-form-field&gt; 中 像下面,你会得到这个错误

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

                  删除父&lt;mat-form-field&gt;标签

                  【讨论】:

                  • 我遇到了这个问题,并且对这类事情进行了标记。删除 mat-form-field 让我的问题消失了。
                  • &lt;mat-form-field&gt; 里面不支持广播组有什么原因吗?我也遇到了这个问题,并没有想到只删除 mat 表单字段标签,因为这似乎不是正确的做法,因为这么多材料 UI 表单示例使用&lt;mat-form-field&gt;。我的 app.module.ts 中定义了表单、选择下拉列表和单选组的所有各种材料表单输入模块,就像许多其他答案参考一样。
                  【解决方案19】:

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

                  请参阅 Stackblitz 上的 full example

                  我在CustomInputComponent 中使用了FormControl (reactive forms),但如果您需要更复杂的表单元素,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>
                  

                  【讨论】:

                    【解决方案20】:

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

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

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

                    【讨论】:

                      【解决方案21】:

                      我有同样的问题

                      问题很简单

                      只有你必须将两个模块导入你的项目

                      MatFormFieldModule MatInputModule

                      【讨论】:

                        【解决方案22】:
                        import {MatInputModule} from '@angular/material/input';
                        
                        
                        
                        @NgModule({
                            imports: [
                                MatInputModule
                            ],
                            exports: [
                                MatInputModule
                            ]
                        })
                        

                        【讨论】:

                        • 欢迎来到stackoverflow。在回答问题时,请添加一些说明,说明您的代码 sn-p 的作用以及为什么它解决了 OP 的问题。欲了解更多信息,请点击此处How to Answer
                        【解决方案23】:

                        由于以下注释元素,我遇到了同样的问题。

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

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

                        【讨论】:

                          【解决方案24】:

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

                          【讨论】:

                            【解决方案25】:

                            您需要将 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
                              ],
                            

                            【讨论】:

                              【解决方案26】:

                              你可以在你的 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>
                              

                              【讨论】:

                              • 这解决了我的问题。你能解释一下appearence = "fill"在这里做什么吗
                              【解决方案27】:

                              在 component.ts 文件中使用提供者

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

                              【讨论】:

                                【解决方案28】:

                                角度 9+ ...材质 9+

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

                                1. 确保您已在 app.module 或要导入组件的 module.ts 中导入 MatFormFieldModule 和 MatInputModule(在嵌套模块的情况下)
                                2. 当您在 mat-form-field 中包装材质按钮或复选框时。查看可以用 mat-form-field mat-form-field 包裹的材料组件列表
                                3. 当您未能在标签中包含 matInput 时。即 ma​​tInput type="number" step="0.01" formControlName="price" />

                                【讨论】:

                                  【解决方案29】:

                                  新更新的 MatInput 模块导入是:

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

                                  根据Angular Materials API

                                  【讨论】:

                                    【解决方案30】:

                                    我已经导入了模块并设置了指令,在再次执行“ng add @angular/material”后它开始工作。也许只需使用 'ng serve' 重新启动应用程序就足够了

                                    【讨论】:

                                      猜你喜欢
                                      • 2019-01-06
                                      • 2021-08-17
                                      • 2021-01-30
                                      • 2020-09-05
                                      • 2019-05-29
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2019-05-24
                                      • 1970-01-01
                                      相关资源
                                      最近更新 更多