La directiva @if en Angular

Intermedio
Angular
Angular
Actualizado: 04/05/2026

La directiva @if es la forma moderna y recomendada de implementar renderización condicional en las plantillas de Angular. Se introdujo en Angular 17 como parte del control flow integrado en el lenguaje de plantillas, se estabilizó en Angular 18 y en Angular 21 es la sintaxis estándar, con mejor rendimiento y una sintaxis más familiar para quienes vienen de otros lenguajes.

Sintaxis básica con else y else if

La estructura de @if recuerda a la sentencia condicional de TypeScript o Java, con una llave que delimita el bloque a renderizar cuando la condición es verdadera y bloques opcionales @else if y @else.

@if (condicion) {
  <p>Condicion cumplida</p>
} @else if (otraCondicion) {
  <p>Condicion alternativa</p>
} @else {
  <p>Ninguna condicion se cumple</p>
}

Un ejemplo realista comprueba el rol del usuario para mostrar una u otra interfaz:

import { Component, signal } from "@angular/core";

@Component({
    selector: "app-dashboard",
    standalone: true,
    template: `
        @if (rol() === "admin") {
            <p>Bienvenido, administrador</p>
            <button (click)="abrirPanelAdmin()">Panel de control</button>
        } @else if (rol() === "editor") {
            <p>Perfil de editor activo</p>
            <button (click)="abrirEditor()">Crear contenido</button>
        } @else {
            <p>Modo solo lectura</p>
        }
    `,
})
export class DashboardComponent {
    rol = signal<"admin" | "editor" | "lector">("lector");

    abrirPanelAdmin() { /* ... */ }
    abrirEditor() { /* ... */ }
}

A diferencia de la antigua directiva *ngIf, @if no necesita importarse con CommonModule. El control flow es parte del compilador de Angular, funciona fuera de la caja y produce un bundle más pequeño.

Alias de expresiones y signals

Una característica muy práctica de @if es la posibilidad de asignar el resultado de la condición a una variable local con la sintaxis as. Esto evita repetir la expresión dentro del bloque y encaja perfectamente con llamadas a signals o pipes asíncronos.

@if (usuario(); as u) {
    <h2>{{ u.nombre }} {{ u.apellido }}</h2>
    <p>Correo: {{ u.email }}</p>
    <p>Rol: {{ u.rol }}</p>
}

El valor devuelto por usuario() (un signal) se captura en u y se reutiliza dentro del bloque sin necesidad de volver a invocar la señal. El mismo patrón funciona con el pipe async sobre observables o promesas:

@if (clientes$ | async; as clientes) {
    <p>Clientes activos: {{ clientes.length }}</p>
    <ul>
        @for (cliente of clientes; track cliente.id) {
            <li>{{ cliente.nombre }}</li>
        }
    </ul>
}

Anidamiento y composición con @else

Los bloques @if se anidan sin restricciones, permitiendo construir árboles condicionales complejos manteniendo la legibilidad. Se combinan con otras directivas del control flow como @for y @switch para cubrir cualquier escenario.

@if (producto(); as p) {
    <article>
        <h2>{{ p.nombre }}</h2>
        <p>Precio: {{ p.precio | currency:"EUR" }}</p>

        @if (p.stock > 0) {
            @if (p.precio < 50) {
                <span class="badge success">Oferta disponible</span>
            } @else if (p.precio < 200) {
                <span class="badge info">Precio estandar</span>
            } @else {
                <span class="badge premium">Premium</span>
            }
            <button (click)="anadirCesta(p)">Añadir a la cesta</button>
        } @else {
            <span class="badge muted">Sin stock</span>
        }
    </article>
} @else {
    <p>Cargando producto...</p>
}
flowchart TD
    A[Signal producto] --> B{"@if producto existe"}
    B -->|Si| C{"@if stock mayor 0"}
    B -->|No| D[Mostrar cargando]
    C -->|Si| E{"@if precio"}
    C -->|No| F[Sin stock]
    E -->|menor 50| G[Oferta]
    E -->|menor 200| H[Estandar]
    E -->|mayor 200| I[Premium]

El diagrama refleja cómo las ramas se componen para cubrir todos los casos visualmente. Angular compila este control flow como código nativo del template engine, sin la sobrecarga de directivas estructurales tradicionales.

La nueva sintaxis reduce en torno a un 30 por ciento el tiempo de renderizado en árboles condicionales profundos, según los benchmarks publicados por el equipo de Angular. Además, el tipado de as queda integrado con el sistema de tipos estricto del template checker.

Caso B2B: flujo de aprobación documental en sector público

Una administración autonómica gestiona la aprobación de subvenciones con un flujo de estados visibles en una SPA Angular para los técnicos revisores. Cada expediente tiene un signal estado que puede valer borrador, en_revision, aprobado o rechazado, y la plantilla usa @if con @else if para renderizar la interfaz apropiada: botón de envío para borradores, panel de comentarios para revisión, resumen firmado para aprobaciones y motivo de rechazo con opción de subsanar en el último caso. La claridad de la sintaxis permite al equipo funcional validar los flujos leyendo la plantilla directamente durante las reuniones de refinamiento, acortando el ciclo de feedback con el negocio.

Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Angular es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Angular

Explora más contenido relacionado con Angular y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Dominar la sintaxis de @if y sus bloques @else y @else if.
  • Diferenciar @if de la antigua directiva estructural *ngIf.
  • Asignar el resultado de una expresión a un alias local y reutilizarlo.
  • Combinar @if con signals, observables y templates asíncronos.