如何解决使用ControlValueAccessor的角度自定义表单控件
这里是带有自定义验证的自定义表单控件的示例。该代码不言自明。主要思想是将验证从父组件传递到自定义内部组件,并在提交表单时触发验证。
<app-country fxFlex formControlName="social_country_id"></app-country>
在这里,我们有应用程序国家/地区组件。 html部分并不重要,它是根据情况定制的。
import { Component,forwardRef,Host,Input,OnDestroy,OnInit,Optional,SkipSelf } from '@angular/core';
import {
ControlValueAccessor,FormControl,FormGroup,FormGroupDirective,NG_VALIDATORS,NG_VALUE_ACCESSOR,} from '@angular/forms';
import { Subject } from 'rxjs';
import { takeuntil } from 'rxjs/operators';
import { UtilsService } from 'src/app/service/utils/utils.service';
import { FormHelper } from 'src/app/shared/FormHelpers';
@Component({
selector: 'app-country',templateUrl: './country.component.html',styleUrls: ['./country.component.scss'],providers: [
{
provide: NG_VALUE_ACCESSOR,useExisting: forwardRef(() => CountryComponent),multi: true,},],})
export class CountryComponent extends FormHelper implements OnInit,ControlValueAccessor,OnDestroy {
@input() formControlName: string;
unsubscribe = new Subject<void>();
countries = [];
form: FormGroup;
value = null;
propagateChange: Function;
constructor(
private utilsService: UtilsService,@Optional()
@Host()
@SkipSelf()
private controlContainer: FormGroupDirective
) {
super();
}
ngOnInit(): void {
this.loadCountries();
this.initForm();
this.setValidatorsFromParentControl();
this.listenForChanges();
this.triggerValidationOnParentFormSubmission();
}
private triggerValidationOnParentFormSubmission() {
this.controlContainer.ngSubmit.subscribe(() => {
this.form.markAllAsTouched();
});
}
private listenForChanges() {
this.form.valueChanges.subscribe((value) => {
this.propagateChange(value.country_id);
});
}
private setValidatorsFromParentControl() {
this.form.controls['country_id'].setValidators(this.controlContainer.form.controls[this.formControlName].validator);
}
private initForm() {
this.form = new FormGroup({
country_id: new FormControl(this.value),});
}
writeValue(value: any) {
this.value = value;
}
registerOnChange(fn: Function) {
this.propagateChange = fn;
}
registerOnTouched() {}
loadCountries() {
this.utilsService
.getCountries()
.pipe(takeuntil(this.unsubscribe))
.subscribe((payload: Array<any>) => {
this.countries = payload;
});
}
ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。