Atualizado: 03/01/2025

Estado do Modelo e Validação - Angular

Estado do Modelo

A aplicação da diretiva ngModel não apenas estabelece a vinculação de dados, mas também permite o rastreamento do estado de um elemento de entrada. Para definir o estado, o Angular aplica classes CSS especiais aos elementos de entrada:

  • Se o elemento de entrada ainda não recebeu foco, a classe ng-untouched é aplicada. Se o campo de entrada já tiver recebido foco, a classe ng-touched é aplicada. O recebimento de foco não precisa ser acompanhado por uma alteração no valor desse campo.

  • Se o valor original do campo de entrada foi alterado, a classe ng-dirty é aplicada. Se o valor não foi alterado desde o carregamento da página, a classe ng-pristine é aplicada ao elemento de entrada.

  • Se o valor no campo de entrada for válido, a classe ng-valid será aplicada. Se o valor for inválido, a classe ng-invalid será aplicada.

Por exemplo, ao carregar uma página web com o seguinte elemento de entrada:

<input class="form-control" name="username" [(ngModel)]="username" />

Será gerada a seguinte marcação HTML:

<input class="form-control ng-untouched ng-pristine ng-valid" name="username" ng-reflect-name="username" />

Validação

Antes de enviar o formulário, é necessário garantir que ele contenha valores corretos. Para essa verificação, é utilizado o mecanismo de validação. No Angular, é possível usar a validação HTML5, aplicada por meio de atributos:

  • required: exige a inserção de um valor.

  • pattern: define uma expressão regular que os dados inseridos devem seguir.

Para usar a validação, definimos o seguinte componente:

import { Component } from "@angular/core";
import { FormsModule } from "@angular/forms";

class User {
    constructor(
        public name: string,
        public email: string,
        public phone: string
    ) {}
}

@Component({
    selector: "my-app",
    standalone: true,
    imports: [FormsModule],
    styles: `
        .alert { color: red; }
        div { margin: 5px 0; }
    `,
    template: `<div>
                    <div>
                        <label>Nome</label><br>
                        <input name="name" [(ngModel)]="user.name" #name="ngModel" required />
                        <div [hidden]="name.valid || name.untouched" class="alert">
                          Nome não informado
                        </div>
                    </div>
                    <div>
                        <label>Email</label><br>
                        <input name="email" [(ngModel)]="user.email" #email="ngModel"
                            required pattern="^[a-zA-Z0-9.!#$%&’*+/=?^_{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$" />
                        <div [hidden]="email.valid || email.untouched" class="alert">
                          Email inválido
                        </div>
                    </div>
                    <div>
                        <label>Telefone</label><br>
                        <input name="phone" [(ngModel)]="user.phone" #phone="ngModel"
                            required pattern="[0-9]{11}" />
                        <div [hidden]="phone.valid || phone.untouched" class="alert">
                          Telefone inválido
                        </div>
                    </div>
                    <button (click)="addUser()">Adicionar</button>
                </div>`
})
export class AppComponent {
    user: User = new User("", "", "");
    addUser() {
        console.log(this.user);
    }
}

Neste exemplo, definimos uma classe User para trabalhar com os dados. Cada campo de entrada está vinculado a uma propriedade do objeto User. Além disso, são definidos requisitos de validação para cada campo usando os atributos required e pattern. Ao lado de cada campo de entrada, há um bloco especial para exibir mensagens de erro:

<div [hidden]="email.valid || email.untouched" class="alert">
  Email inválido
</div>

Aqui, estamos verificando a validade do campo de email. Para isso, utilizamos a variável email, que representa o objeto NgModel associado ao campo de entrada (#email="ngModel"), e verificamos suas propriedades valid e untouched. Se pelo menos uma dessas propriedades for true, o atributo hidden também será true, e o bloco div será oculto. Ou seja, se o campo de email for válido, o bloco será escondido. Caso contrário, uma mensagem de erro será exibida.

Apesar dos erros de validação, ainda podemos clicar no botão e executar o método addUser(), que processará os dados inseridos. No entanto, como os dados são inválidos, o processamento será inútil. Nessa situação, podemos desativar o botão usando a verificação de validade dos campos. Vamos modificar o código do botão da seguinte forma:

<button [disabled]="name.invalid || email.invalid || phone.invalid" 
  (click)="addUser()">Adicionar</button>

Com a expressão [disabled]="name.invalid || email.invalid || phone.invalid", o atributo disabled será definido como true, ou seja, o botão será desativado se pelo menos um dos campos estiver inválido.

Validações em Angular

Estiliando Campos Inválidos

Além de exibir mensagens de erro, é possível estilizar campos inválidos. Para isso, podemos usar a classe ng-invalid aplicada a campos inválidos. Vamos adicionar estilos para campos inválidos:

import { Component } from "@angular/core";
import { FormsModule } from "@angular/forms";

class User {
    constructor(
        public name: string,
        public email: string,
        public phone: string
    ) {}
}

@Component({
    selector: "my-app",
    standalone: true,
    imports: [FormsModule],
    styles: `
        .alert { color: red; }
        div { margin: 5px 0; }    
        input.ng-touched.ng-invalid { border: solid red 2px; }
        input.ng-touched.ng-valid { border: solid green 2px; }
    `,
    template: `<div>
                    <div>
                        <label>Nome</label><br>
                        <input name="name" [(ngModel)]="user.name" #name="ngModel" required />
                    </div>
                    <div>
                        <label>Email</label><br>
                        <input name="email" type="email" [(ngModel)]="user.email" #email="ngModel"
                            required email />
                    </div>
                    <div>
                        <label>Telefone</label><br>
                        <input name="phone" [(ngModel)]="user.phone" #phone="ngModel"
                            required pattern="[0-9]{11}" />
                    </div>
                    <button [disabled]="name.invalid || email.invalid || phone.invalid"
                        (click)="addUser()">Adicionar</button>
                </div>`
})
export class AppComponent {
    user: User = new User("", "", "");
    addUser() {
        console.log(this.user);
    }
}

Neste exemplo, adicionamos estilos para campos inválidos e válidos. Para isso, usamos as classes ng-touched, ng-invalid e ng-valid. Se um campo de entrada for inválido, ele será destacado com uma borda vermelha. Se for válido, a borda será verde.

Estilizando Campos Inválidos
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com