I have several custom form control components in my Angular application, which implement ControlValueAccessor
interface and it works great.
However, when markAsPristine()
is called on parent form, or on my custom control directly I need to update it's state: my custom control is actually have internal control and I need to call markAsPristine()
on it too.
SO, how do I know when markAsPristine()
is called on my control?
The ControlValueAccessor
interface has no members, related to this problem, which I can implement.
"pristine" means the user hasn't changed the value since it was displayed in this form. So given a user has an autocomplete input that looks up airports nearby, when the user selects an option then we set the value of the FormControl to the selected option.
ng-pristine The field has not been modified yet. ng-dirty The field has been modified. ng-valid The field content is valid. ng-invalid The field content is not valid.
Directive To Mark Form Touched First, we target forms that have the formGroup directive. Next, we obtain a reference to the FormGroupDirective instance via dependency injection. The last thing we need to do is register the submit event and call method to mark all form fields as touched.
After thorough investigation I've found out that this functionality is not specifically provided by Angular. I've posted an issue in the official repository regarding this and it's gained feature request status. I hope it will be implemented in near future.
Until then, here's two possible workarounds:
markAsPristine()
@Component({
selector: 'my-custom-form-component',
templateUrl: './custom-form-component.html',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: MyCustomFormComponent,
multi: true
}]
})
export class MyCustomFormComponent implements ControlValueAccessor, OnInit {
private control: AbstractControl;
ngOnInit() {
const origFunc = this.control.markAsPristine;
this.control.markAsPristine = function() {
origFunc.apply(this, arguments);
console.log('Marked as pristine!');
}
}
}
ngDoCheck
Be advised, that this solution could be less performant, but it gives you better flexibility, because you can monitor when pristine state is changed. In the solution above, you will be notified only when markAsPristine()
is called.
@Component({
selector: 'my-custom-form-component',
templateUrl: './custom-form-component.html',
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: MyCustomFormComponent,
multi: true
}]
})
export class MyCustomFormComponent implements ControlValueAccessor, DoCheck {
private control: AbstractControl;
private pristine = true;
ngDoCheck(): void {
if (this.pristine !== this.control.pristine) {
this.pristine = this.control.pristine;
if (this.pristine) {
console.log('Marked as pristine!');
}
}
}
}
And if you need to access the FormControl
instance from your component, please see this question: Get access to FormControl from the custom form component in Angular.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With