¿Puedo implementar condicionalmente la validación en forma reactiva de Angular 2? Tengo este formulario reactivo con 3 campos formControl, uno es una selección y los otros dos son texto de entrada para nombre y apellido. Quiero implementar condicionalmente la validación de nombre y apellido en función de la selección del primer campo que es 'validar por'. Si el usuario selecciona 'byFirstName', solo se debe validar firstName. Si el usuario selecciona 'byLastName', solo se debe validar lastName. Si el usuario selecciona 'byBoth', se deben validar tanto el nombre como el apellido. Creé un plunker para esto. Sólo funciona la validación por Ambos.
ngOnInit() { this.myForm = this._fb.group({ validateBy: ['byFirstName'], firstName: ['', isFirstNameValid(() => (this.validateBy === 'byFirstName' || this.validateBy === 'byBoth'), Validators.required)], lastName: ['', isLastNameValid(() => (this.validateBy === 'byLastName' || this.validateBy === 'byBoth'), Validators.required)], });El problema es que su código evalúa la expresión solo una vez, cuando se crea FormGroup . Debe hacerlo dinámico creando su validador personalizado que evaluará la expresión cada vez que se llame:
this.personForm= this.fb.group({ firstName: ['', Validators.required]; lastName: [ '', conditionalValidator( (() => this.isValidationForLastName === true), Validators.required ) ] }); function conditionalValidator(condition: (() => boolean), validator: ValidatorFn): ValidatorFn { return (control: AbstractControl): {[key: string]: any} => { if (! condition()) { return null; } return validator(control); } }Otra forma de hacerlo sería algo como esto. Parece funcionar en plunker
ngOnInit() { this.myForm = this._fb.group({ validateBy: ['byFirstName'], firstName: [''], lastName: [''], }); this.myForm.get('validateBy').valueChanges.subscribe( (validateBy : string) => { if (validateBy === 'byFirstName' || validateBy === 'byBoth') { this.myForm.get('firstName').setValidators([Validators.required]); this.myForm.get('firstName').updateValueAndValidity(); } if (validateBy === 'byLastName' || validateBy == 'byBoth') { this.myForm.get('lastName').setValidators([Validators.required]); this.myForm.get('lastName').updateValueAndValidity(); } }; ) }Hice una biblioteca solo para esto.
Su solución podría ser algo como:
constructor(private cv: ConditionallyValidateService, private fb: FormBuilder) {} ngOnInit() { this.myForm = this._fb.group({ validateBy: ['byFirstName'], firstName: [''], lastName: [''], }); cv.validate(this.myForm, 'firstName') .using(Validators.required) .when('validateBy') .is('byFirstName') cv.validate(this.myForm, 'lastName') .using(Validators.required) .when('validateBy') .is('byLastName') cv.validate(this.myForm, 'firstName', 'lastName') .using(Validators.required) .when('validateBy') .is('byBoth') }