Angular:mat-form-field 必须包含 MatFormFieldControl

typescript

1个回答

写回答

Luogan0106

2025-07-04 03:15

+ 关注

typescript
typescript

在使用Angular开发应用程序时,我们经常会使用Angular Material来创建用户界面组件。其中一个常用的组件是mat-form-field,它提供了一个美观的表单输入字段。然而,我们在使用mat-form-field时,必须确保它包含一个MatFormFieldControl,这是一个必要的组件,用于管理表单控件的状态和交互。

什么是MatFormFieldControl?

MatFormFieldControl是一个接口,用于定义一个表单控件的行为和属性。它提供了一些方法和属性,用于管理表单控件的值、校验状态和交互。当我们使用mat-form-field时,我们需要将一个实现了MatFormFieldControl接口的组件作为其内部表单控件。

如何使用MatFormFieldControl?

让我们以一个简单的例子来演示如何使用MatFormFieldControl。假设我们有一个表单,其中包含一个输入字段和一个提交按钮。我们想要使用mat-form-field来美化输入字段,并确保它的值符合一定的要求。

首先,我们需要创建一个实现了MatFormFieldControl接口的自定义表单控件组件。我们可以通过继承MatFormFieldControl类来实现这个组件,或者使用MatInput作为基础组件。

typescript

import { Component, OnInit, Input, ElementRef, Self } from '@angular/core';

import { ControlValueAccessor, NgControl } from '@angular/forms';

import { MatFormFieldControl } from '@angular/material/form-field';

import { Subject } from 'rxJS';

@Component({

selector: 'app-custom-input',

templateUrl: './custom-input.component.html',

styleUrls: ['./custom-input.component.sCSS'],

providers: [

{ provide: MatFormFieldControl, useExisting: CustomInputComponent }

]

})

export class CustomInputComponent implements ControlValueAccessor, MatFormFieldControl<string>, OnInit {

static nextId = 0;

@Input() required: boolean;

value: string;

focused = false;

controlType = 'custom-input';

id = <code>custom-input-${CustomInputComponent.nextId++}</code>;

onChange = (_: any) => { };

onTouched = () => { };

stateChanges = new Subject<void>();

constructor(@Self() public ngControl: NgControl, private elementRef: ElementRef<HTMLElement>) {

this.ngControl.valueAccessor = this;

}

ngOnInit() {

const control = this.ngControl.control;

const validators = control.validator ? [control.validator] : [];

const asyncValidators = control.asyncValidator ? [control.asyncValidator] : [];

control.setValidators(validators);

control.setAsyncValidators(asyncValidators);

control.updateValueAndValidity();

}

get empty() {

return !this.value;

}

get shouldLabelFloat() {

return this.focused || !this.empty;

}

get errorState() {

const control = this.ngControl.control;

return control.invalid && control.touched;

}

setDescribedByIds(ids: string[]) {

const controlElement = this.elementRef.nativeElement.querySelector('.custom-input-contAIner');

controlElement.setAttribute('aria-describedby', ids.join(' '));

}

onContAInerClick(event: MouseEvent) {

if ((event.target as Element).tagName.toLowerCase() !== 'input') {

this.elementRef.nativeElement.querySelector('input').focus();

}

}

writeValue(value: string): void {

this.value = value;

this.onChange(value);

this.stateChanges.next();

}

...

}

在上述代码中,我们创建了一个名为CustomInputComponent的自定义表单控件组件,它实现了MatFormFieldControl接口。该组件使用了ControlValueAccessor接口,以便能够与Angular的表单控件进行交互。

我们在组件中定义了一些必要的属性和方法,例如value用于存储输入字段的值,focused用于记录输入字段是否获得焦点,controlType用于标识控件类型等等。这些属性和方法都是MatFormFieldControl接口的要求。

在组件的模板中,我们使用mat-form-field来包装输入字段,并使用matInput指令将其与mat-form-field关联起来。我们还使用一些Angular Material提供的样式和指令来美化输入字段。

html

<mat-form-field>

<input matInput [placeholder]="placeholder" [required]="required" [id]="id" [value]="value" (input)="onChange($event.target.value)" (blur)="onTouched()" [class.floating]="shouldLabelFloat">

<label [for]="id" [class.floating]="shouldLabelFloat">{{placeholder}}</label>

<mat-error *ngIf="errorState">{{errorMessage}}</mat-error>

</mat-form-field>

然后,我们可以在应用的其他部分使用CustomInputComponent来创建美化的输入字段。

html

<form>

<app-custom-input placeholder="Username" required></app-custom-input>

<button type="submit">Submit</button>

</form>

在本文中,我们学习了如何使用mat-form-field和MatFormFieldControl来创建美化的输入字段。我们创建了一个自定义的表单控件组件,实现了MatFormFieldControl接口,并通过继承MatFormFieldControl类或使用MatInput作为基础组件来实现它。通过使用自定义表单控件组件,我们可以轻松地创建可重用的美化输入字段,并确保其值符合我们的要求。

举报有用(4分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号