我正在尝试使用自定义电话号码输入控件添加一个表单字段。我以https://material.angular.io/components/form-field/examples中的电话为例。
代码如下:
<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
<div [formGroup]="parts" class="example-tel-input-container">
<input class="example-tel-input-element" formControlName="area" size="3">
<span class="example-tel-input-spacer">–</span>
<input class="example-tel-input-element" formControlName="exchange" size="3">
<span class="example-tel-input-spacer">–</span>
<input class="example-tel-input-element" formControlName="subscriber" size="4">
</div>
===
但是出现以下错误: 错误错误:mat-form-field必须包含MatFormFieldControl。
答案 0 :(得分:25)
需要import
两个模块,并将其添加到“进出口”部分。
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
@NgModule ({
imports: [ MatFormFieldModule, MatInputModule ],
exports: [ MatFormFieldModule, MatInputModule ]
})
每个人最想念的这个'/'
字符。如果您看到Angular Material Documentation,他们也会错过此内容(最后检查时间为2020年6月16日,不知道他们是否已更新)。我以澄清为例
<!-- Wrong -->
<mat-form-field>
<input matInput>
</mat-form-field>
<!-- Right -->
<mat-form-field>
<input matInput />
</mat-form-field>
仔细查看代码段。 <input
开始时,它必须以/>
结尾,但是大多数人都错过了/
(反斜杠)字符。
答案 1 :(得分:3)
确保已导入 MatInputModule ,并且<mat-form-field>
包含带有<input>
指令的matInput / matSelect
。
答案 2 :(得分:3)
此外,不要忘记在输入标签中写入name属性:
name="yourName"
答案 3 :(得分:3)
关闭输入标签的另一个可能的问题。如果从其中一个Angular示例(https://material.angular.io/components/datepicker/overview)复制代码,则可能会得到以下代码:
<mat-form-field appearance="fill">
<mat-label>Choose a date</mat-label>
<input matInput [matDatepicker]="picker">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
输入应带有关闭标签(斜杠):
<input matInput [matDatepicker]="picker" />
答案 4 :(得分:1)
导入MatInputModule
,解决了我的错误
答案 5 :(得分:1)
如果您在代码中使用任何“input”标签以及“mat-form-field”,请确保在 input 标签中包含“matInput”
如果'mat-form-field'的子标签中存在任何*ngIf,则在'mat-form-field'标签中指定*ngIf条件
答案 6 :(得分:0)
您需要将您的课程指定为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 }
]
})
答案 7 :(得分:-1)
错误说mat-form-field
应该至少包含一个用于输入的表单字段。
例如:matInput
mat-select
等
根据您的情况,您可以在example-tel-input-example.html中的输入字段中添加matInput
标记。同样,您也可以将mat-form-field
移到example-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">–</span>
<mat-form-field>
<input matInput class="example-tel-input-element" formControlName="exchange" size="3">
</mat-form-field>
<span class="example-tel-input-spacer">–</span>
<mat-form-field>
<input matInput class="example-tel-input-element" formControlName="subscriber" size="4">
</mat-form-field>
</div>
注意:mat-icon
或mat-hint
不能被视为表单域