mat-form-field必须包含MatFormFieldControl

时间:2017-10-12 08:42:29

标签: angular angular-material2

我们正在努力在公司建立自己的表格 - 组件。我们正试图将材料设计的组件包装成这样:

字段:

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

但是我们得到了&#34; mat-form-field必须包含一个MatFormFieldControl&#34;在控制台中。我想这与mat-form-field没有直接包含matInput-field有关。但它包含它,它只是在进行ng-content投影。

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

38 个答案:

答案 0 :(得分:237)

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

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

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

希望它有所帮助。

更多信息here

答案 1 :(得分:47)

解决方案1 ​​

MatInputModule

中导入app.module.ts
import { MatInputModule } from '@angular/material';

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

解决方案2

检查matInput的拼写,确保它区分大小写

<input matInput type="text" />

答案 2 :(得分:12)

引用官方文档here

  

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

     

如果尚未向表单字段控件添加,则会发生此错误   形式领域。如果您的表单字段包含本机或   element,确保您已将matInput指令添加到其中并具有   导入MatInputModule。可以充当表单字段的其他组件   控制包括,和任何自定义表单   您已创建的字段控件。

答案 3 :(得分:11)

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



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

答案 4 :(得分:8)

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

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

答案 5 :(得分:6)

如果您在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提出了另一种解决方案:为mat-form-field移动* ngIf:

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

答案 6 :(得分:5)

我不确定它是否可以这么简单,但我遇到了同样的问题,更改&#34; mat-input&#34;到&#34; matInput&#34;在输入字段中解决了问题。在你的情况下,我看到&#34; matinput&#34;并且它导致我的应用程序抛出相同的错误。

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

<强>&#34; matinput&#34;

enter image description here

<强>&#34; matInput&#34;

enter image description here

答案 7 :(得分:3)

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>

答案 8 :(得分:3)

新更新的MatInput模块导入为:

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

根据Angular Materials API

答案 9 :(得分:3)

角9+ ...材料9 +

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

  1. 确保已在要导入组件的app.module或module.ts中导入了MatFormFieldModule和MatInputModule(如果是嵌套模块)
  2. 将材料按钮或复选框包装在垫子形式字段中时。请参阅可以用mat-form-field mat-form-field
  3. 包裹的材料组件列表。
  4. 当您未能在标签中包含matInput时。即 matInput type =“ number” step =“ 0.01” formControlName =“ price” />

答案 10 :(得分:2)

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

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

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

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ EventFormComponent ],
      imports: [
        # HttpClientTestingModule,
        # RouterTestingModule,
        ReactiveFormsModule,
        MatFormFieldModule,
        MatInputModule,
        BrowserAnimationsModule,
        # TranslateModule.forRoot(),
      ],
    })
    .compileComponents();
  }));

答案 11 :(得分:2)

您可以在mat-form-field标记内设置外观=“ fill”,它对我有用

var authenticationProperties = new AuthenticationProperties
        {
            AllowRefresh = true,
            IsPersistent = true
        };

await _signInManger.SignInWithClaimsAsync(user, authenticationProperties, claims.AsEnumerable());

答案 12 :(得分:2)

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

答案 13 :(得分:2)

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

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

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

答案 14 :(得分:2)

您在输入代码中错过了matInput指令。

答案 15 :(得分:1)

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

当导入中缺少 'MatInputModule' 时会发生此错误,

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

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

在 module.ts 文件中导入 MatInputModule 将有助于解决问题。

答案 16 :(得分:1)

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

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

答案 17 :(得分:1)

这意味着您不会像导入 MatInputModule 一样

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

@NgModule({ 进口:[ MatFormField 模块, 垫输入模块 ] }) 导出类 AppModule { }

答案 18 :(得分:1)

我也有这个问题,我的模板中有<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>

答案 19 :(得分:1)

在我的情况下,在输入元素上缺少了“ onChanges()”的右括号,因此显然根本没有呈现输入元素:

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

答案 20 :(得分:1)

如果以上所有主要代码结构/配置答案都不能解决您的问题,请检查另外一件事:确保您没有以某种方式使<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无效的错误,那么您可能会遇到 try { final Optional<Thread> observerThread = Thread.getAllStackTraces().keySet() .stream() .filter(it -> it.getName().startsWith(YOUR_OBSERVER_THREAD_PREFIX)) .filter(it -> it.getState().equals(RUNNABLE)) .findFirst(); //need to figure out how long will be enough for you final int maxThreadSleep = 30; int i = 0; while (observerThread.isPresent() && observerThread.get().getState().equals(RUNNABLE) && i < maxThreadSleep) { Thread.sleep(2); i++; } } catch (InterruptedException e) { System.out.println(e); } } 错误。无论如何,这只是调试时要寻找的另一件事。

答案 21 :(得分:1)

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

请参阅Stackblitz上的full example

我在FormControl内使用了CustomInputComponentreactive 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>

答案 22 :(得分:0)

如果任何人在尝试嵌套<html> <head> <title>Video Streaming </title> </head> <body> <h1> Live Video Streaming </h1> <img src="{{ url_for('video_feed') }}"> </body> </html> 后仍然遇到此错误,请加油!它在<mat-checkbox>标记内不起作用。

答案 23 :(得分:0)

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

答案 24 :(得分:0)

保证 100% 解决 只需将 matInput 指令添加到每个输入、matselect 和 mat-chip-list enter image description here

答案 25 :(得分: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指令才为我解决了此错误。

答案 26 :(得分:0)

对我来说,错误是由于 <input> 中缺少 <mat-form-field></mat-form-field> 和 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>

答案 27 :(得分:0)

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

答案 28 :(得分:0)

仅因错误地将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>

答案 29 :(得分:0)

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

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

答案 30 :(得分:0)

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

答案 31 :(得分:0)

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

  1. MatInputModule
  2. MatFormFieldModule
  3. ReactiveFormsModule

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

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

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

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

Angular Docs: Reactive Forms

Angular Docs: Reactive Forms Module

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

请记住,这些需要直接导入到您组件的模块中,而不是您正在使用它们的组件中。如果我没记错的话,在Angular 2中,我们将整个Angular Material模块集导入了我们的主app模块,并且然后直接将我们需要的内容导入每个组件中。当前的方法比IMO效率更高,因为如果只使用其中一部分,我们可以保证导入整个Angular Material模块集。

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

答案 32 :(得分:0)

MatRadioModule在MatFormField中不起作用。 docs

  

当您尚未将表单域控件添加到您的表单时,会发生此错误   表格栏位。如果您的表单字段包含本机或   元素,请确保已将matInput指令添加到该元素并具有   导入的MatInputModule。 可以用作表单字段的其他组件   控制包括 和任何自定义形式   您创建的字段控件。

答案 33 :(得分: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>

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

答案 34 :(得分:0)

如果有人试图将height=10, aspect=2嵌套在<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> 标签

答案 35 :(得分:0)

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

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

因此请不要在“提交”按钮周围使用此标签

答案 36 :(得分:-1)

您可能错过了导入 MatInputModule

答案 37 :(得分:-1)

我有同样的问题

问题很简单

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

MatFormFieldModule MatInputModule