validacao_orientada_a_template - VWJavascript/Alurapic GitHub Wiki

Validação orientada a template

E aí? Cadastrou muita fotos? Um ponto importante é validarmos a entrada do usuário brecando qualquer dado inconsistente. Por exemplo, não é incomum termos campos obrigatório como é o caso do título da foto. A boa notícia é que o Angular já possui uma infraestrutura pronta para nos ajudar com validações.

O primeiro passo para usarmos validação orientada a template é importarmos FormsModule em AppModule. Contudo, já importamos esse módulo para que a diretiva ngModel funcionasse em nossos templates.

Se quisermos tornar nosso campo obrigatório, podemos usar o atributo required que não é exclusivo do Angular, mas do HTML5:

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

<!-- código anterior omitido -->
<div class="form-group">
    <label>Título</label>
    <input required name="titulo" [(ngModel)]="foto.titulo" class="form-control"  autocomplete="off">
</div>

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

E se o campo estiver inválido, ou seja, vazio? Vamos adicionar uma mensagem para o usuário, logo abaixo do input do nome:

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

<!-- código anterior omitido -->
<div class="form-group">

    <label>Título</label>

    <input required name="titulo" [(ngModel)]="foto.titulo" class="form-control"  autocomplete="off">

    <span class="form-control alert-danger">
        Título obrigatório
    </span> 

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

Se recarregarmos nossa página podemos verificar um problema logo de cara. A mensagem "Título obrigatório" é exibida prontamente, e mesmo se completarmos o campo, ela continua sendo exibida. Na prática, só podemos ver a mensagem se o campo estiver inválido. Há outro problema também: como o Angular saberá consultar se o campo é válido ou inválido? Ele baterá na porta do HTML5 para saber?

A solução dos dois problemas é a mesma: precisamos ter acesso a um objeto especial que representa o elemento do formulário e via Angular consultá-lo para saber se ele é válido ou não. Para criar esse objeto, usamos a seguinte sintaxe:

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

<!-- código anterior omitido -->
<div class="form-group">

    <label>Título</label>

    <input 
        required 
        name="titulo"
        #titulo = "ngModel" 
        [(ngModel)]="foto.titulo" 
        class="form-control"  autocomplete="off">

</div>

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

Veja que adicionei #titulo = "ngModel" ao input do título. Essa sintaxe cria uma variável local que não é novidade para nós, porém seu valor é a diretiva ngModel. Essa sintaxe um tanto estranha permite acessarmos o objeto que representa a validação com campo através do nome da variável:

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

<!-- código anterior omitido -->
<div class="form-group">

    <label>Título</label>

    <input 
        required 
        name="titulo" 
        #titulo = "ngModel" 
        [(ngModel)]="foto.titulo" 
        class="form-control"  autocomplete="off">

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

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

A diretiva ngIf exibe o elemento no qual foi adicionada se o seu valor for true e o esconde quando for false. É por isso que seu valor é a expressão titulo.invalid, isto é, só exibiremos a tag quando o título for inválido. Mas isso ainda não é suficiente.

Já podemos recarregar o formulário e testar o resultado:

image

Um olhar atento dirá que o botão Salvar continua habilitado e podemos salvar nossa foto. Será que podemos desativá-lo enquanto nosso formulário estiver inválido? Veja, não quero saber de um campo específico, mas do formulário como um todo. Felizmente podemos fazer isso.

Precisamos primeiro declarar uma variável de template, local, para nosso formulário:

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

<form #meuForm="ngForm" (submit)="cadastrar($event)" class="row">

Veja que inicializamos a variável #meuForm com o valor ngForm.

Agora, em nosso botão:

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

<!-- código anterior omitido -->

<button type="submit" class="btn btn-primary" [disabled]="meuForm.form.invalid">Salvar</button>

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

Já podemos testar nosso formulário.

image

Nosso formulário e sua validação segue o padrão validação orientada a template (template-driven form). Porém, existe outra forma de validação configurada em nosso componente.

⚠️ **GitHub.com Fallback** ⚠️