feat(forms): AbstractControl to store raw validators in addition to combined validators function (#37881)

This commit refactors the way we store validators in AbstractControl-based classes:
in addition to the combined validators function that we have, we also store the original list of validators.
This is needed to have an ability to clean them up later at destroy time (currently it's problematic since
they are combined in a single function).

The change preserves backwards compatibility by making sure public APIs stay the same.
The only public API update is the change to the `AbstractControl` class constructor to extend the set
of possible types that it can accept and process (which should not be breaking).

PR Close #37881
This commit is contained in:
Andrew Kushnir
2020-07-01 18:16:49 -07:00
parent d72b1e44c6
commit ad7046b934
3 changed files with 212 additions and 27 deletions

View File

@ -263,6 +263,57 @@ describe('FormControl', () => {
expect(c.valid).toEqual(true);
});
it('should override validators using `setValidators` function', () => {
const c = new FormControl('');
expect(c.valid).toEqual(true);
c.setValidators([Validators.minLength(5), Validators.required]);
c.setValue('');
expect(c.valid).toEqual(false);
c.setValue('abc');
expect(c.valid).toEqual(false);
c.setValue('abcde');
expect(c.valid).toEqual(true);
// Define new set of validators, overriding previously applied ones.
c.setValidators([Validators.maxLength(2)]);
c.setValue('abcdef');
expect(c.valid).toEqual(false);
c.setValue('a');
expect(c.valid).toEqual(true);
});
it('should override validators by setting `control.validator` field value', () => {
const c = new FormControl('');
expect(c.valid).toEqual(true);
// Define new set of validators, overriding previously applied ones.
c.validator = Validators.compose([Validators.minLength(5), Validators.required]);
c.setValue('');
expect(c.valid).toEqual(false);
c.setValue('abc');
expect(c.valid).toEqual(false);
c.setValue('abcde');
expect(c.valid).toEqual(true);
// Define new set of validators, overriding previously applied ones.
c.validator = Validators.compose([Validators.maxLength(2)]);
c.setValue('abcdef');
expect(c.valid).toEqual(false);
c.setValue('a');
expect(c.valid).toEqual(true);
});
it('should clear validators', () => {
const c = new FormControl('', Validators.required);
expect(c.valid).toEqual(false);
@ -412,6 +463,59 @@ describe('FormControl', () => {
expect(c.valid).toEqual(true);
}));
it('should override validators using `setAsyncValidators` function', fakeAsync(() => {
const c = new FormControl('');
expect(c.valid).toEqual(true);
c.setAsyncValidators([asyncValidator('expected')]);
c.setValue('');
tick();
expect(c.valid).toEqual(false);
c.setValue('expected');
tick();
expect(c.valid).toEqual(true);
// Define new set of validators, overriding previously applied ones.
c.setAsyncValidators([asyncValidator('new expected')]);
c.setValue('expected');
tick();
expect(c.valid).toEqual(false);
c.setValue('new expected');
tick();
expect(c.valid).toEqual(true);
}));
it('should override validators by setting `control.asyncValidator` field value',
fakeAsync(() => {
const c = new FormControl('');
expect(c.valid).toEqual(true);
c.asyncValidator = Validators.composeAsync([asyncValidator('expected')]);
c.setValue('');
tick();
expect(c.valid).toEqual(false);
c.setValue('expected');
tick();
expect(c.valid).toEqual(true);
// Define new set of validators, overriding previously applied ones.
c.asyncValidator = Validators.composeAsync([asyncValidator('new expected')]);
c.setValue('expected');
tick();
expect(c.valid).toEqual(false);
c.setValue('new expected');
tick();
expect(c.valid).toEqual(true);
}));
it('should clear async validators', fakeAsync(() => {
const c = new FormControl('value', [asyncValidator('expected'), otherAsyncValidator]);