我要解决的任务:
创建可重复使用的输入组件包装器,以节省编写表单模板时的时间。
我的意思示例:
无需编写以下模板:
<form [formGroup]="myForm">
<mat-form-field>
<input matInput placeholder="Email" [formControl]="email" required>
<mat-error *ngIf="email.invalid">{{getErrorMessage()}}</mat-error>
</mat-form-field>
<form>
我想写:
<form [formGroup]="myForm">
<my-input-component [form]="myForm" [myFormControl]="email" [myFormControlName]="'email'" [label]="'Email'"></my-input-component>
</form>
我的输入组件的外观如下:
<mat-form-field [formGroup]="form">
<input
matInput
type="text"
[attr.inputmode]="inputMode"
[placeholder]="label"
[formControlName]="myFormControlName"
/>
<mat-error class="errors" *ngIf="myFormControl.invalid">
<div>{{ getError() }}</div>
</mat-error>
</mat-form-field>
这按原样工作,但我不知道这是否是将FormGroup和FormControls作为绑定传递的好方法。
在线搜索后,我不断遇到 NG_CONTROL_VALUE_ACCESSOR ,是否可以在我的场景中使用它感到有些困惑。
从使用滑块作为表单控件或类似性质的意义上讲,我不希望这些组件是“自定义的”,而只是希望“包装器”节省一些时间。
有关该主题的任何建议或建议,将不胜感激!
答案 0 :(得分:0)
推荐使用的方法是实现ControlValueAccessor
interface,就像您已经发现的那样。该接口是专门为创建自定义表单控件而创建的。它将在您的可重用组件和Forms API之间建立一座桥梁。
这是带有标签的可重用输入字段的一个小示例。您也可以在此模板中添加错误消息。
组件
import { Component, OnInit, Input, Self, Optional } from '@angular/core';
import { ControlValueAccessor, NgControl } from '@angular/forms';
@Component({
selector: 'custom-input',
templateUrl: './custom-input.component.html',
styleUrls: ['./custom-input.component.css']
})
export class CustomInputComponent implements OnInit, ControlValueAccessor {
@Input() disabled: boolean;
@Input() label: string;
@Input() placeholder: string = '';
@Input() type: 'text' | 'email' | 'password' = 'text';
value: any = '';
constructor(
// Retrieve the dependency only from the local injector,
// not from parent or ancestors.
@Self()
// We want to be able to use the component without a form,
// so we mark the dependency as optional.
@Optional()
private ngControl: NgControl
) {
if (this.ngControl) {
this.ngControl.valueAccessor = this;
}
}
ngOnInit() {}
/**
* Write form value to the DOM element (model => view)
*/
writeValue(value: any): void {
this.value = value;
}
/**
* Write form disabled state to the DOM element (model => view)
*/
setDisabledState(isDisabled: boolean): void {
this.disabled = isDisabled;
}
/**
* Update form when DOM element value changes (view => model)
*/
registerOnChange(fn: any): void {
// Store the provided function as an internal method.
this.onChange = fn;
}
/**
* Update form when DOM element is blurred (view => model)
*/
registerOnTouched(fn: any): void {
// Store the provided function as an internal method.
this.onTouched = fn;
}
private onChange() {}
private onTouched() {}
}
模板
<label>{{ value }}</label>
<input [type]="type"
[placeholder]="placeholder"
[value]="value"
[disabled]="disabled"
(input)="onChange($event.target.value)"
(blur)="onTouched()" />
您可以查看本文Creating a custom form component in Angular以获取更多详细信息。