ControlValueAccessors 在过去几个月突然出现在我面前,我对为什么或何时应该使用它们而不是@Input与我的反应式表单一起使用感到有些困惑。
这是迄今为止我如何使用反应式表单的示例代码:
@Component({
selector: 'app-my-component',
template: `<input [formControl]="form.get('specificControlName')" />`
// or the alternative method of [formGroup]="form" and formControlName="specificControlName"
})
export class MyComponent {
@Input() form: FormGroup; // passed in formGroup
ngOnInit() {
form.valueChanges.pipe(
// do rxjs magic here
).subscribe(value => {
// do something with the value
})
}
}
Run Code Online (Sandbox Code Playgroud)
响应式表单保存表单的状态,因此我甚至可以从父组件访问该状态。我还可以访问所有不同的NgControl属性,如valid,disabled,dirty,和touched。
ControlValueAccessors 提供了什么,而这种使用反应式表单的方式没有提供?什么是一些使用情况下,ControlValueAccessors优于工作@Input和@Output一般的?
编辑:
https://medium.com/angular-in-depth/angular-nested-reactive-forms-using-cvas-b394ba2e5d0d
在本文中,作者提到了以下主要区别:
实现嵌套表单的三种方式:
...
- 通过 Input 将 FormGroup 的句柄传递给子组件并在子模板中引用它。有几个很好的教程。
但是使用这种方法的缺点是您将父表单组与子组的表单组紧密绑定。
- 使用复合 CVA。
优点:高度可重用,便携。更好的封装(组件的内部表单控件不一定需要对父组件可见)。当您有更多数量的表单模块(通常是一个大型项目)时,最好使用此方法。
缺点:需要实现 CVA 接口会导致样板代码。
这很有趣,但它引发了更多问题:为什么以及何时不希望您的内部表单控件对父级可见?便携是什么意思?
还:
import { Component, OnInit } from '@angular/core';
import { ControlValueAccessor,NG_VALUE_ACCESSOR, NG_VALIDATORS, FormGroup,FormControl, Validator, Validators,AbstractControl, ValidationErrors } from "@angular/forms";
@Component({
selector: 'app-address-info',
templateUrl: './address-info.component.html',
styleUrls: ['./address-info.component.css']
})
export class AddressInfoComponent implements OnInit, ControlValueAccessor {
public addressForm: FormGroup = new FormGroup({
addressLine: new FormControl("",[Validators.required]),
areacode: new FormControl('', [Validators.required, Validators.maxLength(5)])
});
constructor() { }
ngOnInit() {
}
public onTouched: () => void = () => {};
writeValue(val: any): void {
val && this.addressForm.setValue(val, { emitEvent: false });
}
registerOnChange(fn: any): void {
console.log("on change");
this.addressForm.valueChanges.subscribe(fn);
}
registerOnTouched(fn: any): void {
console.log("on blur");
this.onTouched = fn;
}
setDisabledState?(isDisabled: boolean): void {
isDisabled ? this.addressForm.disable() : this.addressForm.enable();
}
}
Run Code Online (Sandbox Code Playgroud)
当您将 aFormGroup传入ControlValueAccessorComponent 时,作者正在使用FormGroup与传入对象相同的结构在组件内部初始化一个新的内部。那么直接传入FormGroup本身不是更好吗?或者封装提供了什么好处?
EDIT2:这是一个关于这个主题的有趣视频:
小智 2
每当您使用本机 HTML 元素(输入、选择、按钮、表单等)时,请使用标准反应式表单 API
例如,当您必须使用自定义 HTML 元素(即 mat-list、mat-table、ag-grid-table 等)时,请使用 ControlValueAccessor,原因是它是一个充当Angular 表单 API 和 DOM 之间桥梁的接口元素。ControlValueAccessor 示例
| 归档时间: |
|
| 查看次数: |
1911 次 |
| 最近记录: |