angular - 简单的控制值访问器
问题描述
什么是 Angular 的控制值访问器
我尝试过@input、@output 方法,但在验证过程中变得复杂,特别是对于 ngModel
期望包含第 3 方 UI 控件的包装器组件能够轻松工作
解决方案
简单来说,控制值访问器: 目的:拥有一个自定义 UI 子组件,它是一个使用第三方 UI 小部件的包装器,可能像 PrimeNg、ngx-bootstrap 的 DatePicker。包装器可以轻松地与表单控件(父组件)同步,而无需使用 @Inputs/Outputs。主要是,您将如何通知父母有关验证的信息。轻松通过 CVA。
示例:假设您想从 ngx-bootstrap 构建一个 datepicker,如下所示:假设您有一个使用自定义 DatePicker 的表单:
表格.ts:
currentDate: Date = new Date();
onDateChanged($event){
// do something with the received date..Maybe call an api for the selectedDate's data
}
表格.html:
<custom-date-picker id="selectedDate" name="fieldName" [(ngModel)]="currentDate" (onDateChanged)="onDateChanged($event)"></custom-date-picker>
创建一个包装组件:CustomDatePicker.ts:
@Component({
selector: 'custom-date-picker',
templateUrl: 'custom-date-picker.component.html',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => IpxDatePickerComponent),
multi: true
}
]
})
export class CustomDatePickerComponent implements ControlValueAccessor {
onChanged: any = () => {};
// tslint:disable-next-line:no-empty
onTouched: any = () => {};
writeValue(obj: any): void {
if (obj) {
this.selectDate(obj);
}
}
registerOnChange(fn: any): void {
this.onChanged = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
// tslint:disable-next-line:no-empty
setDisabledState?(isDisabled: boolean): void {}
selectDate(val): void {
this.selectedDate = val;
}
dateChanged = (e: Date): void => {
if (e) {
this.onChanged(e);// this statement should have ideally set your parent forms ngModel variable to the new selected date.
this.onDateChanged.emit(e);
}
};
}
CustomDatePicker.html:
<input type="text" #datePicker="bsDatepicker" placeholder="Datepicker" (bsValueChange)="dateChanged($event)" [(ngModel)]="selectedDate" [bsConfig]="bsConfig" />
就是这样,现在如果您看到,您的表单的 ngModel 将同步。并且子控件和父控件将与 selectedDate 以及 touch 等验证同步。
实际上,我发现这种方法很有用,因为在使用常规 @inputs、@outputs 实现时,我发现了很多同步问题。
我们现在甚至可以通过 CVA 使用它们,但它们主要用于操作其他数据而不是包装目的(在这种情况下为日期)
推荐阅读
- wordpress - z-index 根据数字不起作用时如何解决?
- python - 根据属性更改节点形状
- google-analytics - Google Analytics(分析)中缺少电子商务数据警告消息
- awk - 如果在 Linux 中仅匹配特定值,如何打印列?
- firebase - 无法从 Firebase 存储中获取实际的字符串下载 url,并且只返回“未来的实例”
' 甚至使用 async/await - javascript - Passport JS 和自定义 async/await 函数
- java - 等待电子邮件
- sql - 由 CSV 支持的 Flink SQL 表,带有标题
- spring - 无法从可选加载配置数据:configserver:http//localhost:8012
- google-cloud-platform - 如何在大型查询计划作业上创建警报并在失败时发送电子邮件?