typescript Angular:mat-form-field 必须包含一个 MatFormFieldControl

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/53935928/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:45:00  来源:igfitidea点击:

Angular: mat-form-field must contain a MatFormFieldControl

javascripthtmlangularformstypescript

提问by user3590450

I am trying to add a form field with custom telephone number input control. I used the example of the phone from https://material.angular.io/components/form-field/examples.

我正在尝试添加带有自定义电话号码输入控件的表单字段。我使用了https://material.angular.io/components/form-field/examples中的电话示例。

Here is the code:

这是代码:

    <mat-form-field>
  <example-tel-input placeholder="Phone number" required></example-tel-input>
  <mat-icon matSuffix>phone</mat-icon>
  <mat-hint>Include area code</mat-hint>

import {FocusMonitor} from '@angular/cdk/a11y';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {Component, ElementRef, Input, OnDestroy} from '@angular/core';
import {FormBuilder, FormGroup} from '@angular/forms';
import {MatFormFieldControl} from '@angular/material';
import {Subject} from 'rxjs';

/** @title Form field with custom telephone number input control. */
@Component({
  selector: 'form-field-custom-control-example',
  templateUrl: 'form-field-custom-control-example.html',
  styleUrls: ['form-field-custom-control-example.css'],
})
export class FormFieldCustomControlExample {}

/** Data structure for holding telephone number. */
export class MyTel {
  constructor(public area: string, public exchange: string, public subscriber: string) {}
}

/** Custom `MatFormFieldControl` for telephone number input. */
@Component({
  selector: 'example-tel-input',
  templateUrl: 'example-tel-input-example.html',
  styleUrls: ['example-tel-input-example.css'],
  providers: [{provide: MatFormFieldControl, useExisting: MyTelInput}],
  host: {
    '[class.example-floating]': 'shouldLabelFloat',
    '[id]': 'id',
    '[attr.aria-describedby]': 'describedBy',
  }
})
export class MyTelInput implements MatFormFieldControl<MyTel>, OnDestroy {
  static nextId = 0;

  parts: FormGroup;
  stateChanges = new Subject<void>();
  focused = false;
  ngControl = null;
  errorState = false;
  controlType = 'example-tel-input';
  id = `example-tel-input-${MyTelInput.nextId++}`;
  describedBy = '';

  get empty() {
    const {value: {area, exchange, subscriber}} = this.parts;

    return !area && !exchange && !subscriber;
  }

  get shouldLabelFloat() { return this.focused || !this.empty; }

  @Input()
  get placeholder(): string { return this._placeholder; }
  set placeholder(value: string) {
    this._placeholder = value;
    this.stateChanges.next();
  }
  private _placeholder: string;

  @Input()
  get required(): boolean { return this._required; }
  set required(value: boolean) {
    this._required = coerceBooleanProperty(value);
    this.stateChanges.next();
  }
  private _required = false;

  @Input()
  get disabled(): boolean { return this._disabled; }
  set disabled(value: boolean) {
    this._disabled = coerceBooleanProperty(value);
    this.stateChanges.next();
  }
  private _disabled = false;

  @Input()
  get value(): MyTel | null {
    const {value: {area, exchange, subscriber}} = this.parts;
    if (area.length === 3 && exchange.length === 3 && subscriber.length === 4) {
      return new MyTel(area, exchange, subscriber);
    }
    return null;
  }
  set value(tel: MyTel | null) {
    const {area, exchange, subscriber} = tel || new MyTel('', '', '');
    this.parts.setValue({area, exchange, subscriber});
    this.stateChanges.next();
  }

  constructor(fb: FormBuilder, private fm: FocusMonitor, private elRef: ElementRef<HTMLElement>) {
    this.parts = fb.group({
      area: '',
      exchange: '',
      subscriber: '',
    });

    fm.monitor(elRef, true).subscribe(origin => {
      this.focused = !!origin;
      this.stateChanges.next();
    });
  }

  ngOnDestroy() {
    this.stateChanges.complete();
    this.fm.stopMonitoring(this.elRef);
  }

  setDescribedByIds(ids: string[]) {
    this.describedBy = ids.join(' ');
  }

  onContainerClick(event: MouseEvent) {
    if ((event.target as Element).tagName.toLowerCase() != 'input') {
      this.elRef.nativeElement.querySelector('input')!.focus();
    }
  }


  }

===

===

example-tel-input-example.html

示例电话输入示例.html

  <div [formGroup]="parts" class="example-tel-input-container">
      <input class="example-tel-input-element" formControlName="area" size="3">
      <span class="example-tel-input-spacer">&ndash;</span>
      <input class="example-tel-input-element" formControlName="exchange" size="3">
      <span class="example-tel-input-spacer">&ndash;</span>
      <input class="example-tel-input-element" formControlName="subscriber" size="4">
    </div>

===

===

But I get the following error: ERROR Error: mat-form-field must contain a MatFormFieldControl.

但我收到以下错误:错误错误:mat-form-field must contains a MatFormFieldControl。

回答by Kimwan Ogot

Make sure MatInputModuleis imported and <mat-form-field>contains <input>with matInput / matSelectdirectives.

确保MatInputModule导入并<mat-form-field>包含<input>matInput / matSelect指令。

https://github.com/angular/material2/issues/7898

https://github.com/angular/material2/issues/7898

回答by prisar

Import MatInputModule, solved my error

导入MatInputModule,解决了我的错误

回答by johnluetke

You need to specify your class as a provider for MatFormFieldControl

您需要将您的类指定为提供者 MatFormFieldControl

https://material.angular.io/guide/creating-a-custom-form-field-control#providing-our-component-as-a-matformfieldcontrol

https://material.angular.io/guide/creating-a-custom-form-field-control#providing-our-component-as-a-matformfieldcontrol

@Component({
  selector: 'form-field-custom-control-example',
  templateUrl: 'form-field-custom-control-example.html',
  styleUrls: ['form-field-custom-control-example.css'],
  providers: [
    { provide: MatFormFieldControl, useExisting: FormFieldCustomControlExample }   
  ]
})

回答by gena_ukr79

Also, don't forget to write the name attribute in the input tag:

另外,不要忘记在 input 标签中写入 name 属性:

name="yourName"

回答by Shatu

Need to Import two module import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; then also add the module in import and export

需要导入两个模块 import { MatFormFieldModule } from '@angular/material/form-field'; 从'@angular/material/input' 导入 { MatInputModule }; 然后也在导入和导出中添加模块

and the most thing which everybody miss this '/' character. if you see the angular material documentation, they also miss this (check 19 may 2020, don't know they even update or not).

以及每个人都想念这个“/”字符的最重要的事情。如果您看到 angular material 文档,他们也会错过这个(检查 2020 年 5 月 19 日,不知道他们甚至更新与否)。

<!-- Wrong -->
<mat-form-field>
  <input matInput>
</mat-form-field>

<!-- Right -->
<mat-form-field>
  <input matInput />
</mat-form-field>

Look at the snippet carefully. when <inputbegin it must close with />but most people miss the /(backslash) character. I think, this is the solution.

仔细看片断。当<input开始它必须关闭/>,但大多数人都错过了/(反斜杠)字符。我想,这就是解决方案。

回答by Amit Chigadani

Error says that mat-form-fieldshould contain at least one form field from which input is taken.

错误表示mat-form-field应至少包含一个从中获取输入的表单字段。

Ex : matInputmat-selectetc.

例如:matInputmat-select等。

In your case you may add matInputtag to your input fields within example-tel-input-example.html. And also you could move mat-form-fieldinside example-tel-input-examplecomponent and add it against each matInputfield.

在您的情况下,您可以matInput在 example-tel-input-example.html 中的输入字段中添加标签。您也可以mat-form-fieldexample-tel-input-example组件内部移动并将其添加到每个matInput字段中。

<div [formGroup]="parts" class="example-tel-input-container">
      <mat-form-field>
         <input matInput class="example-tel-input-element" formControlName="area" size="3">
      </mat-form-field>
      <span class="example-tel-input-spacer">&ndash;</span>
      <mat-form-field>
          <input matInput class="example-tel-input-element" formControlName="exchange" size="3">
      </mat-form-field>
      <span class="example-tel-input-spacer">&ndash;</span>
      <mat-form-field>
          <input matInput class="example-tel-input-element" formControlName="subscriber" size="4">
      </mat-form-field>
</div>

Note: mat-iconor mat-hintcannot be considered as form-fields

注意mat-iconmat-hint不能被视为表单域