Estoy tratando de implementar un formulario basado en modelos en Angular 2. La estructura de mi modelo de datos es la siguiente:
archive (FormGroup) name (FormControl) description (FormControl) connection (FormGroup) url (FormControl) authentication (FormGroup) username (FormControl) password (FormControl)
Dentro de este modelo de datos, se requiere el nombre de nivel superior, pero el campo de descripción es opcional. Puedo aplicar un validador requerido al nombre y omitir un validador de la descripción.
Para la conexión, quiero que sea opcional, pero si hay una conexión, su URL se vuelve obligatoria. De manera similar para el modelo de autenticación de la conexión: es opcional, pero si está presente, se requerirá el nombre de usuario y la contraseña.
Estoy tratando de entender cómo configurar validadores para hacer cumplir estas reglas. Intenté simplemente omitir cualquier validador del grupo de formularios de conexión, pero eso parecía requerirme tener una conexión. He visto tutoriales en línea que explican cómo implementar la validación personalizada en grupos de formularios anidados, pero nada que describa cómo hacer que todo el grupo de formularios anidados sea opcional.
¿Existe una forma sencilla de implementar este modelo con Angular 2 FormGroup?
Tuve una necesidad similar y aquí hay una manera de resolverlo:
this.form = new FormGroup({ 'name': new FormControl(null, Validators.required), 'description': new FormControl(null), 'connection': new FormGroup({ 'url': new FormControl(null), 'authentification': new FormGroup({ 'username': new FormControl(null, Validators.minLength(5)), 'password': new FormControl(null), }, this.authentificationValidator.bind(this)), }, this.connectionValidator.bind(this)) });
Las 2 funciones del validador:
authentificationValidator(g: FormGroup): any { const username = g.get('username').value; const password = g.get('password').value; if( (username && !password) || (!username && password) ) { return { authentification: true }; } } connectionValidator(g: FormGroup): any { const url = g.get('url').value; const authentification = g.get('authentification'); const username = authentification.get('username').value; const password = authentification.get('password').value; if( (username || password) && !url ) { return { connection: true }; } }
Y para la salida, si completa solo el nombre, aún tendrá:
{ "name": null, "description": null, "connection": { "url": null, "authentification": { "username": null, "password": null } } }
Por lo tanto, debe crear condicionalmente un nuevo objeto para tener:
{ "name": null, "description": null, "connection": null }