compondo_validadores - VWJavascript/Alurapic GitHub Wiki

Compondo validadores

Agora tenho a seguinte pergunta: e se quisermos que o campo titulo, além de obrigatório, tenha como tamanho mínimo quatro dígitos? Para isso, podemos usar Validators.minLength que já vem com o Angular. Porém, perceba que queremos aplicar duas validações para o mesmo campo, isto é, queremos compor uma validação que é composta por outras duas:

// alurapic/client/app/cadastro/cadastro.component.ts

import { Component, Input } from '@angular/core';
import { Http, Headers } from '@angular/http';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
    moduleId: module.id,
    selector: 'cadastro',
    templateUrl: './cadastro.component.html' 
})
export class CadastroComponent { 

    http: Http;
    meuForm: FormGroup;

    constructor(http: Http, fb: FormBuilder) {

        this.http = http;

        this.meuForm = fb.group({
            titulo: ['', Validators.compose(
                [Validators.required, Validators.minLength(4)]
            )],
            url: ['', Validators.required],
            descricao: [''],
        });
    }

    // código posterior omitido

Para ficar tudo redondo, temos que dar uma mensagem diferente para erro de validação e outra para o tamanho do campo. Podemos consultar as variáveis locais que criamos que apontam para nossos Controls. Se houver algum erro de validação, o objeto erros será criado e nele adicionadas propriedades que equivalem a cada validador que adicionamos. O valor dessas propriedade será true caso tenha ocorrido uma violação da validação e false caso o campo seja válido.

Vamos alterar nossa marcação:

<!-- alurapic/client/app/cadastro/cadastro.component.html -->

<div class="container">

    <form [formGroup]="meuForm" (submit)="cadastrar($event)" class="row">
        <div class="col-md-6">
            <div class="form-group">
                <label>Título</label>
                <input  [(ngModel)]="foto.titulo"  formControlName="titulo" name="titulo" class="form-control"  autocomplete="off">

                <div *ngIf="!meuForm.controls.titulo.valid">

                    <span *ngIf="meuForm.controls.titulo.errors.required" class="form-control alert-danger">
                        Título obrigatório
                    </span>

                    <span *ngIf="meuForm.controls.titulo.errors.minlength" class="form-control alert-danger">
                        Título deve ter no mínimo 4 caracteres
                    </span>     

                </div>
            </div>
            <!-- código posterior omitido -->

Agora é só testar. Por fim, que tal exibirmos o título da imagem na página em destaque e também exibir no canto direito da página a imagem assim que sua URL for digitada? Nosso formulário ficará assim:

<div class="container">
    <h1 class="text-center">{{foto.titulo}}</h1><!-- novidade aqui -->
    <form [formGroup]="meuForm" (submit)="cadastrar($event)" class="row">
        <div class="col-md-6">
            <div class="form-group">
                <label>Título</label>
                <input name="titulo" formControlName="titulo" [(ngModel)]="foto.titulo" class="form-control" autocomplete="off">

                <div *ngIf="!meuForm.controls.titulo.valid">
                    <span *ngIf="meuForm.controls.titulo.errors.required" class="form-control alert-danger">
                        Título obrigatório
                    </span>
                    <span *ngIf="meuForm.controls.titulo.errors.minlength" class="form-control alert-danger">
                        Título deve ter no mínimo 4 caracteres
                    </span>     
                </div>     
            </div>
            <div class="form-group">
                <label>URL</label>
                <input name="url"  formControlName="url" [(ngModel)]="foto.url" class="form-control" autocomplete="off">
                <span *ngIf="!meuForm.controls.url.valid" class="form-control alert-danger">
                    URL obrigatória
                </span>     
            </div>
            <div class="form-group">
                <label>Descrição</label>
                <textarea name="descricao"  formControlName="descricao" [(ngModel)]="foto.descricao" class="form-control" autocomplete="off">
                </textarea>
            </div>

            <button type="submit" class="btn btn-primary" [disabled]="!meuForm.valid">
                Salvar
            </button>
             <a [routerLink]="['']" class="btn btn-primary">Voltar</a>
            <hr>
        </div>
       <!-- novidade aqui -->
        <div class="col-md-6">
            <foto url="{{foto.url}}" titulo="{{foto.titulo}}">
            </foto>
        </div>
    </form>    
</div>
⚠️ **GitHub.com Fallback** ⚠️