Reputation: 8511
In my Angular app I have a complex entity that can be created in multiple ways: manually, by uploading json files, by importing from another url, etc.
For each case described above, I have build a separate form, using Reactive Forms, in separate components.
All the other form fields are different, except the field for the atrribute called name
.
The formControl attached to the name
attribute has the following definition:
name: new FormControl(this.initialValue, [
Validators.required,
Validators.minLength(3),
Validators.maxLength(10)
])
Now, I don't like that I have to repeat the same definition for this form control on every reactive form constructor, which, as I said before, are in separate components.
Here are some code snippets:
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('')
});
I have build a simple Stackblitz example: https://stackblitz.com/edit/angular-tyjnlq. (for simplification, in the example the forms are in same component)
Question: How can I save this form control and include it in every form?
Upvotes: 0
Views: 521
Reputation: 27491
To build reusable form, we have to use ControlValueAccessor API.
What is 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;
}
}
For Detailed explanationCheck this Blog
Upvotes: 1
Reputation: 1
What about storing the Form Definition of the control in a Service which adds the control to the Group with the Form builder like so dynamically addControl to formgroup Angular 5
Upvotes: 0