Angular 2 Reactive Form - 重用单个表单控件
Angular 2 Reactive Form - Reuse individual form control
在我的 Angular 应用程序中,我有一个可以通过多种方式创建的复杂实体:手动、通过上传 json 文件、从另一个 url 导入等。
对于上述每种情况,我都在单独的组件中使用Reactive Forms构建了一个单独的表单。 =18=]
除了名为 name
.
的属性字段外,所有其他表单字段都不同
附加到 name
属性的 formControl 具有以下定义:
name: new FormControl(this.initialValue, [
Validators.required,
Validators.minLength(3),
Validators.maxLength(10)
])
现在,我不喜欢我必须在每个反应式表单构造函数上重复此表单控件的相同定义,正如我之前所说,它们位于 单独的组件中 .
以下是一些代码片段:
this.formA = new FormGroup({
name: new FormControl(this.initialValue, [
Validators.required,
Validators.minLength(3),
Validators.maxLength(10)
]),
fooControl1: new FormControl(''),
fooControl2: new FormControl('')
});
this.formB = new FormGroup({
name: new FormControl(this.initialValue, [
Validators.required,
Validators.minLength(3),
Validators.maxLength(10)
]),
barControl: new FormControl('')
});
我构建了一个简单的 Stackblitz 示例:https://stackblitz.com/edit/angular-tyjnlq。
(为简化起见,在示例中,表单位于同一组件中)
问题:
如何保存此表单控件并将其包含在每个表单中?
将控件的表单定义存储在服务中如何使用表单构建器将控件添加到组中,就像这样
要构建可重用的表单,我们必须使用 ControlValueAccessor API。
什么是 CVA?
According to Angular documentation, ControlValueAccessor Defines an interface that acts as a bridge between the Angular forms
API and a native element in the DOM.
@Component({
selector: "app-nameform",
templateUrl: "./nameform.component.html",
styleUrls: ["./nameform.component.css"],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: NameformComponent,
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: NameformComponent,
multi: true
}
]
})
export class NameformComponent implements OnInit, ControlValueAccessor {
form: FormGroup;
onTouched: any;
onChange:any;
constructor() {
this.form = new FormGroup({
name: new FormControl("", [
Validators.required,
Validators.minLength(3),
Validators.maxLength(10)
])
});
this.form.valueChanges.subscribe(value=>{
this.onChange(value);
this.onTouched();
})
}
ngOnInit() {}
writeValue(value: any) {
value && this.form.setValue(value, {emitEvent:false});
}
registerOnChange(fn: any) {
this.onChange = fn;
}
registerOnTouched(fn: any) {
this.onTouched = fn;
}
get controls() {
return this.form.controls;
}
validate(control:AbstractControl){
return this.form.valid;
}
}
在我的 Angular 应用程序中,我有一个可以通过多种方式创建的复杂实体:手动、通过上传 json 文件、从另一个 url 导入等。
对于上述每种情况,我都在单独的组件中使用Reactive Forms构建了一个单独的表单。 =18=]
除了名为 name
.
附加到 name
属性的 formControl 具有以下定义:
name: new FormControl(this.initialValue, [
Validators.required,
Validators.minLength(3),
Validators.maxLength(10)
])
现在,我不喜欢我必须在每个反应式表单构造函数上重复此表单控件的相同定义,正如我之前所说,它们位于 单独的组件中 .
以下是一些代码片段:
this.formA = new FormGroup({
name: new FormControl(this.initialValue, [
Validators.required,
Validators.minLength(3),
Validators.maxLength(10)
]),
fooControl1: new FormControl(''),
fooControl2: new FormControl('')
});
this.formB = new FormGroup({
name: new FormControl(this.initialValue, [
Validators.required,
Validators.minLength(3),
Validators.maxLength(10)
]),
barControl: new FormControl('')
});
我构建了一个简单的 Stackblitz 示例:https://stackblitz.com/edit/angular-tyjnlq。 (为简化起见,在示例中,表单位于同一组件中)
问题: 如何保存此表单控件并将其包含在每个表单中?
将控件的表单定义存储在服务中如何使用表单构建器将控件添加到组中,就像这样
要构建可重用的表单,我们必须使用 ControlValueAccessor API。
什么是 CVA?
According to Angular documentation, ControlValueAccessor Defines an interface that acts as a bridge between the Angular forms API and a native element in the DOM.
@Component({
selector: "app-nameform",
templateUrl: "./nameform.component.html",
styleUrls: ["./nameform.component.css"],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: NameformComponent,
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: NameformComponent,
multi: true
}
]
})
export class NameformComponent implements OnInit, ControlValueAccessor {
form: FormGroup;
onTouched: any;
onChange:any;
constructor() {
this.form = new FormGroup({
name: new FormControl("", [
Validators.required,
Validators.minLength(3),
Validators.maxLength(10)
])
});
this.form.valueChanges.subscribe(value=>{
this.onChange(value);
this.onTouched();
})
}
ngOnInit() {}
writeValue(value: any) {
value && this.form.setValue(value, {emitEvent:false});
}
registerOnChange(fn: any) {
this.onChange = fn;
}
registerOnTouched(fn: any) {
this.onTouched = fn;
}
get controls() {
return this.form.controls;
}
validate(control:AbstractControl){
return this.form.valid;
}
}