<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Angular Firebase</title>
    <description>The latest articles on Forem by Angular Firebase (@angularfirebase).</description>
    <link>https://forem.com/angularfirebase</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F821%2Fd43c326b-2812-4d5d-a7e0-f13d3a9567d7.png</url>
      <title>Forem: Angular Firebase</title>
      <link>https://forem.com/angularfirebase</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/angularfirebase"/>
    <language>en</language>
    <item>
      <title>MCP Skills vs MCP Tools: La forma correcta de configurar MCP Server</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sun, 22 Mar 2026 08:59:35 +0000</pubDate>
      <link>https://forem.com/angularfirebase/mcp-skills-vs-mcp-tools-la-forma-correcta-de-configurar-mcp-server-24ck</link>
      <guid>https://forem.com/angularfirebase/mcp-skills-vs-mcp-tools-la-forma-correcta-de-configurar-mcp-server-24ck</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Las skills y las herramientas MCP no son lo mismo — y confundirlos tiene un costo real. Aprende la diferencia, los problemas reales y cómo combinarlos para un flujo de trabajo agéntico que sí funcione.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Todo el mundo habla de MCP. Todo el mundo habla de skills.&lt;/p&gt;

&lt;p&gt;La mayoría los usa como sinónimos — y ese es exactamente el problema.&lt;/p&gt;

&lt;p&gt;No son lo mismo. No resuelven el mismo problema. Y si usas el incorrecto, lo vas a sentir: alucinaciones, contexto desbordado, agentes que pierden el hilo y flujos de trabajo que se rompen bajo presión.&lt;/p&gt;

&lt;p&gt;Vamos a resolverlo.&lt;/p&gt;




&lt;h2&gt;
  
  
  El modelo mental
&lt;/h2&gt;

&lt;p&gt;Piénsalo como una cocina.&lt;/p&gt;

&lt;p&gt;Las &lt;strong&gt;herramientas MCP&lt;/strong&gt; son tus electrodomésticos e ingredientes — el horno, el refrigerador, los vegetales frescos. Capacidad pura. Sin ellos, no se cocina nada.&lt;/p&gt;

&lt;p&gt;Los &lt;strong&gt;skills&lt;/strong&gt; son tus recetas — las instrucciones paso a paso que le dicen a un chef exactamente cómo convertir esos ingredientes en algo bueno. Sin ellas, tienes poder, pero sin dirección.&lt;/p&gt;

&lt;p&gt;Un agente con solo herramientas MCP &lt;em&gt;puede&lt;/em&gt; hacer cosas, pero no necesariamente sabe &lt;em&gt;cómo&lt;/em&gt; hacerlas bien. Un agente con solo skills tiene excelentes instrucciones, pero no puede actuar sobre ellas.&lt;/p&gt;

&lt;p&gt;Necesitas los dos.&lt;/p&gt;




&lt;h2&gt;
  
  
  ¿Qué es una herramienta MCP?
&lt;/h2&gt;

&lt;p&gt;El &lt;strong&gt;Model Context Protocol&lt;/strong&gt; es un estándar abierto — ahora bajo la Agentic AI Foundation de la Linux Foundation — que le da a los agentes de IA una forma estandarizada de conectarse a sistemas externos: bases de datos, APIs, sistemas de archivos, GitHub, Slack, tu Angular CLI.&lt;/p&gt;

&lt;p&gt;Cuando conectas un servidor MCP a tu cliente —ya sea Claude Code, la CLI de Gemini o un agente personalizado—, este accede a un conjunto de &lt;strong&gt;herramientas deterministas y tipadas&lt;/strong&gt;. Cada herramienta tiene un esquema claro de entrada y salida. Cuando el agente la llama, se ejecuta — sin interpretación, sin riesgo de alucinación a nivel de ejecución. Es una llamada de API estructurada, no una sugerencia.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"angular-cli"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@angular/cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP es como el agente &lt;em&gt;alcanza fuera de sí mismo&lt;/em&gt;. Es el sistema nervioso.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usa MCP cuando el agente necesite:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leer o escribir en un sistema real (base de datos, sistema de archivos, API)&lt;/li&gt;
&lt;li&gt;Ejecutar acciones con entradas y salidas claras y auditables.&lt;/li&gt;
&lt;li&gt;Conectarse a herramientas que no controlas&lt;/li&gt;
&lt;li&gt;Integrar múltiples servicios a través de una interfaz consistente.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ¿Qué es un skill?
&lt;/h2&gt;

&lt;p&gt;Un &lt;strong&gt;skill&lt;/strong&gt; es una carpeta que contiene un archivo Markdown (con frontmatter YAML) más scripts y recursos opcionales. No es ejecutable por sí solo — es un playbook.&lt;/p&gt;

&lt;p&gt;Cuando la solicitud de un usuario coincide con los criterios de relevancia de un skill, el agente carga esas instrucciones dinámicamente y las sigue. Es como darle al agente memoria procedural de nivel experto, bajo demanda.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;angular-component-review&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Revisar componentes Angular para cumplimiento de Signals y arquitectura standalone&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Revisión de Componente Angular&lt;/span&gt;

Al revisar un componente Angular:
&lt;span class="p"&gt;1.&lt;/span&gt; Verificar que todo el estado use &lt;span class="sb"&gt;`signal()`&lt;/span&gt; o &lt;span class="sb"&gt;`computed()`&lt;/span&gt; — nunca mutación directa
&lt;span class="p"&gt;2.&lt;/span&gt; Confirmar que el componente es &lt;span class="sb"&gt;`standalone: true`&lt;/span&gt;
&lt;span class="p"&gt;3.&lt;/span&gt; Asegurar que no queden dependencias de &lt;span class="sb"&gt;`NgModule`&lt;/span&gt;
&lt;span class="p"&gt;4.&lt;/span&gt; Validar que se use &lt;span class="sb"&gt;`@if`&lt;/span&gt; / &lt;span class="sb"&gt;`@for`&lt;/span&gt; en lugar de &lt;span class="sb"&gt;`*ngIf`&lt;/span&gt; / &lt;span class="sb"&gt;`*ngFor`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El agente lo carga solo cuando es relevante. Cuando no lo es — no te cuesta nada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usa un skill cuando el agente lo necesite:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Seguir un proceso o checklist consistente.&lt;/li&gt;
&lt;li&gt;Aplicar experiencia específica del dominio (tus estándares de código, criterios de revisión).&lt;/li&gt;
&lt;li&gt;Codificar conocimiento que no cambia frecuentemente.&lt;/li&gt;
&lt;li&gt;Reutilizar el mismo flujo de trabajo en distintas conversaciones.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Los desventajas reales
&lt;/h2&gt;

&lt;p&gt;Aquí es donde la mayoría de las guías se detienen. No deberían.&lt;/p&gt;

&lt;h3&gt;
  
  
  MCP: El Impuesto de Tokens
&lt;/h3&gt;

&lt;p&gt;Cada herramienta MCP que conectas inyecta su esquema completo en la ventana de contexto &lt;em&gt;antes de que el agente procese un solo mensaje&lt;/em&gt;. Cada herramienta cuesta 550–1,400 tokens. Conecta GitHub, Slack y Sentry y estás mirando &lt;strong&gt;55,000 tokens quemados de entrada&lt;/strong&gt; — más de un cuarto del límite de 200k de Claude antes de hacer cualquier trabajo real.&lt;/p&gt;

&lt;p&gt;Un equipo reportó conectar tres servidores MCP y consumir &lt;strong&gt;143,000 de 200,000 tokens&lt;/strong&gt; solo en definiciones de herramientas. Al agente le quedaban 57,000 tokens para la conversación real.&lt;/p&gt;

&lt;p&gt;Y si usas Gemini con su ventana de contexto de 1M+ tokens, podrías pensar que puedes ignorar esto. No lo hagas. Incluso si te sobra espacio, inyectar 55,000 tokens de esquema JSON crudo en cada iteración de la conversación aumenta la latencia, incrementa los costos de la API y diluye el enfoque del modelo.&lt;/p&gt;

&lt;p&gt;La buena noticia: clientes modernos como Claude Code y la CLI de Gemini han adoptado el &lt;strong&gt;progressive discovery&lt;/strong&gt; para MCP — cargando solo nombres y descripciones de herramientas al inicio (~20–50 tokens cada una), y obteniendo los esquemas completos solo cuando el agente realmente necesita una herramienta. El overhead de tokens cayó ~85%. Pero esto solo funciona si tu configuración MCP está preparada para usarlo — y la mayoría todavía no lo está.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skills: El Problema de la Desactualización
&lt;/h3&gt;

&lt;p&gt;Los skills son archivos Markdown. No se actualizan solos. Si tus patrones de Angular evolucionan — digamos que migraste de &lt;code&gt;setInput()&lt;/code&gt; a la nueva API declarativa en Angular 20 — tu Skill sigue enseñando la forma antigua hasta que alguien lo actualice manualmente.&lt;/p&gt;

&lt;p&gt;Cuantos más skills creas, mayor es la carga de mantenimiento. Y si un skill está sutilmente equivocado, el agente lo seguirá con confianza — sin error, solo output silenciosamente incorrecto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ambos: El problema de selección
&lt;/h3&gt;

&lt;p&gt;Dale a un agente demasiadas herramientas o demasiados skills y empieza a tomar las decisiones equivocadas — llama a la herramienta incorrecta, activa el playbook equivocado, o los combina de formas que producen instrucciones contradictorias. Los expertos recomiendan no superar &lt;strong&gt;10–15 herramientas MCP activas&lt;/strong&gt; al mismo tiempo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cómo combinarlos
&lt;/h2&gt;

&lt;p&gt;El patrón más poderoso es usarlos como capas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capa 1 — MCP provee acceso.&lt;/strong&gt;&lt;br&gt;
Conecta solo lo que el agente genuinamente necesita para la tarea actual. Angular CLI, una base de datos, un sistema de archivos. Mantenlo simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capa 2 — Skills proveen experiencia.&lt;/strong&gt;&lt;br&gt;
Crea un Skill que le diga al agente &lt;em&gt;cómo&lt;/em&gt; usar esas herramientas en tu contexto específico. No solo "ejecuta el Angular CLI" — sino "al migrar un componente, ejecuta &lt;code&gt;ng generate&lt;/code&gt; con estos flags, luego valida contra estos patrones."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capa 3 — Skills pueden orquestar MCP.&lt;/strong&gt;&lt;br&gt;
Un skill puede definir un flujo de trabajo multipaso que llame a múltiples herramientas MCP en secuencia. Ejemplo: un skill de "Deploy &amp;amp; Notify" que usa el MCP de GitHub para hacer push, un MCP de CI/CD para lanzar el build, y un MCP de Slack para notificar al equipo — todo bajo un playbook coherente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;angular-migration-workflow&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Flujo completo para migrar un componente Angular a patrones v21&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# Flujo de Migración&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; Usa el MCP del Angular CLI para verificar la versión actual del componente
&lt;span class="p"&gt;2.&lt;/span&gt; Ejecuta &lt;span class="sb"&gt;`ng update`&lt;/span&gt; para el paquete afectado
&lt;span class="p"&gt;3.&lt;/span&gt; Aplica el schematic de migración zoneless
&lt;span class="p"&gt;4.&lt;/span&gt; Revisa el output contra el Skill de angular-component-review
&lt;span class="p"&gt;5.&lt;/span&gt; Ejecuta los tests y reporta resultados
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Guía de Decisión Práctica
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situación&lt;/th&gt;
&lt;th&gt;Usar&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Necesito consultar una base de datos real&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito seguir un checklist de code review&lt;/td&gt;
&lt;td&gt;Skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito hacer push a GitHub&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito aplicar el formato de commits de mi equipo&lt;/td&gt;
&lt;td&gt;Skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito leer una API en vivo&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito enseñarle al agente mis reglas de arquitectura Angular&lt;/td&gt;
&lt;td&gt;Skill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Necesito acceso Y proceso consistente&lt;/td&gt;
&lt;td&gt;Ambos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Mejorando el Flujo de Trabajo
&lt;/h2&gt;

&lt;p&gt;Algunos patrones que realmente funcionan en producción:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Un servidor MCP por dominio.&lt;/strong&gt; No cargues todo al mismo tiempo. Crea configuraciones separadas para "desarrollo Angular", "despliegue" y "comunicación" — y activa solo la que necesitas para cada sesión.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Versiona tus Skills como código.&lt;/strong&gt; Ponlos en tu repositorio. Revísalos cuando actualices tu stack. Un Skill para patrones de Angular 19 te va a perjudicar activamente en Angular 21.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Usa Skills para escribir guardrails de MCP.&lt;/strong&gt; En lugar de confiar en que el agente sepa cuándo llamar a una acción MCP destructiva, escribe un Skill que diga explícitamente: &lt;em&gt;"Antes de ejecutar cualquier &lt;code&gt;ng update&lt;/code&gt;, siempre crea un branch de git primero."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Mide tu presupuesto de contexto.&lt;/strong&gt; Antes de que el agente haga cualquier trabajo real, conoce cuántos tokens consume tu configuración MCP. Si superas el 30% de tu ventana de contexto solo en definiciones de herramientas, tienes un problema de configuración.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Deja que el agente mantenga los Skills simples.&lt;/strong&gt; Para áreas de cambio rápido — como mantener actualizadas las convenciones de versión de Angular de tu equipo — deja que el agente actualice el archivo Skill cuando se lo indiques. Es más rápido que hacerlo manualmente y mantiene el Skill honesto.&lt;/p&gt;




&lt;h2&gt;
  
  
  La conclusión
&lt;/h2&gt;

&lt;p&gt;MCP les da a los agentes la capacidad de actuar. Los skills les enseñan cómo actuar bien.&lt;/p&gt;

&lt;p&gt;El debate de "MCP vs Skills" es falso. La pregunta real es: &lt;em&gt;¿necesitas acceso, experiencia, o ambos?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;En la mayoría de los flujos de trabajo reales con Angular, necesitas los dos. Un agente que puede ejecutar tu CLI, pero no conoce tu arquitectura, es solo una forma más rápida de cometer los mismos errores. Un agente que conoce tus patrones, pero no puede tocar tu proyecto real, es solo un buscador caro.&lt;/p&gt;

&lt;p&gt;Usados juntos, con límites claros y configuración lean, son la base del desarrollo agéntico que realmente funciona.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Anteriormente escribí sobre &lt;a href="https://www.yeou.dev/articulos/angular-21-mcp-migraciones" rel="noopener noreferrer"&gt;Angular 21, MCP y el fin de las migraciones manuales&lt;/a&gt; — un buen punto de partida si eres nuevo en la configuración del servidor MCP para Angular.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>mcp</category>
      <category>spanish</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Actualizando a Angular 21 usando ng mcp</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sat, 13 Dec 2025 07:47:54 +0000</pubDate>
      <link>https://forem.com/angularfirebase/angular-21-y-mcp-el-fin-de-las-migraciones-manuales-4ocn</link>
      <guid>https://forem.com/angularfirebase/angular-21-y-mcp-el-fin-de-las-migraciones-manuales-4ocn</guid>
      <description>&lt;p&gt;Angular 21 introduce el servidor Model Context Protocol (MCP). Aprende cómo conectar tu editor de IA directamente al CLI de Angular para automatizar actualizaciones, refactorizaciones y cambios arquitectónicos como Zoneless.&lt;/p&gt;

&lt;p&gt;Solíamos tratar a la IA como a un extraño inteligente. Copiábamos y pegábamos mensajes de error o contenidos de archivos en ChatGPT, esperando que entendiera la arquitectura de nuestro proyecto. Era útil, pero estaba ciega.&lt;/p&gt;

&lt;p&gt;Con Angular 21, ese extraño se ha mudado a tu casa.&lt;/p&gt;

&lt;p&gt;El lanzamiento del servidor MCP del CLI de Angular (&lt;code&gt;ng mcp&lt;/code&gt;) marca un cambio fundamental en la forma en que mantenemos las aplicaciones.&lt;/p&gt;

&lt;p&gt;No es solo un nuevo comando; es un protocolo que permite a los agentes de IA (como Cursor, Windsurf o VS Code Copilot) "entrevistar" a tu proyecto, entender tus restricciones específicas y ejecutar migraciones que realmente compilen.&lt;/p&gt;

&lt;p&gt;He aquí por qué la era de la "migración manual" podría estar terminando, y cómo sobrevivir al nuevo flujo de trabajo agéntico.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es MCP? (El "puerto USB" para la IA)
&lt;/h2&gt;

&lt;p&gt;El Model Context Protocol (MCP) es un estándar abierto que permite a los modelos de IA conectarse a herramientas y datos locales.&lt;/p&gt;

&lt;p&gt;Piénsalo de esta manera:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Antes de MCP:&lt;/strong&gt; Pegabas &lt;code&gt;angular.json&lt;/code&gt; en el chat para que la IA conociera tu estructura de archivos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Después de MCP:&lt;/strong&gt; La IA simplemente pregunta al CLI de Angular: "Oye, lista todos los proyectos en este espacio de trabajo", y el CLI responde con la estructura exacta, los objetivos de compilación y las dependencias de bibliotecas.&lt;/p&gt;

&lt;p&gt;En Angular 21, el CLI es un servidor MCP. Expone "herramientas" que tu editor de IA puede llamar directamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuración: 5 minutos para un Angular "agéntico"
&lt;/h2&gt;

&lt;p&gt;La configuración es sorprendentemente trivial porque el equipo de Angular la integró directamente en el CLI.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Inicializar el servidor.
&lt;/h3&gt;

&lt;p&gt;En tu terminal del espacio de trabajo de Angular 21:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este comando no inicia un demonio; genera los fragmentos de configuración que necesitas para tu IDE específico.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Conectar tu editor (por ejemplo, Cursor).
&lt;/h3&gt;

&lt;p&gt;Si estás usando Cursor (que probablemente deberías estar usando si te interesa MCP), crea o edita &lt;code&gt;.cursor/mcp.json&lt;/code&gt; o, si usas Antigravity, crea o edita &lt;code&gt;.gemini/antigravity/mcp.json&lt;/code&gt; en la raíz de tu proyecto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"angular-cli"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@angular/cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mcp"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para verificar la configuración de CURSOR, haz clic en los tres puntos en la esquina superior derecha y selecciona "Agent Settings".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxz5vt7pnp80r01rg9y5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqxz5vt7pnp80r01rg9y5.png" alt="Pasos de configuración de cursor" width="628" height="850"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Luego haz clic en "Tools &amp;amp; MCP". Si todo está configurado correctamente, deberías ver angular listado como servidor MCP instalado con el nombre de la herramienta como "ai_tutor".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx1wqb8h5gqvobmhm4xc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx1wqb8h5gqvobmhm4xc.png" alt="Servidor Angular MCP listado." width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para verificar la configuración de Antigravity, haz clic en los tres puntos en la esquina superior derecha y selecciona "MCP Servers".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F061revsz4nxdbs2wdv96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F061revsz4nxdbs2wdv96.png" alt="Gestionar servidores MCP Antigravity." width="594" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Luego verás listado 'angular-cli' y podrás gestionar las herramientas, teniendo la capacidad de habilitarlas o deshabilitarlas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbginapctq8cx8oiw9or8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbginapctq8cx8oiw9or8.png" alt="Interruptor herramientas angular" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[NOTE]&lt;br&gt;
La flag &lt;code&gt;-y&lt;/code&gt; es crucial para evitar que el mensaje "Press y to install" bloquee el proceso en segundo plano.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Herramientas disponibles
&lt;/h2&gt;

&lt;p&gt;El servidor MCP del CLI de Angular proporciona varias herramientas para ayudarte en tu flujo de trabajo de desarrollo. Por defecto, las siguientes herramientas están habilitadas:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Herramienta&lt;/th&gt;
&lt;th&gt;Solo lectura&lt;/th&gt;
&lt;th&gt;Solo local&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ai_tutor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;find_examples&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_best_practices&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;list_projects&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;angular.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;onpush_zoneless_migration&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;search_documentation&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Herramientas experimentales
&lt;/h3&gt;

&lt;p&gt;Algunas herramientas se proporcionan en estado experimental / vista previa. Puedes habilitarlas explícitamente:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Herramienta&lt;/th&gt;
&lt;th&gt;Solo lectura&lt;/th&gt;
&lt;th&gt;Solo local&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;modernize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  La "killer app": Migraciones conscientes del contexto
&lt;/h2&gt;

&lt;p&gt;¿Por qué pasar por este problema? Porque las &lt;strong&gt;migraciones conscientes del contexto&lt;/strong&gt; superan con creces a los esquemáticos estándar.&lt;/p&gt;

&lt;p&gt;Los scripts tradicionales de &lt;code&gt;ng update&lt;/code&gt; son rígidos. Siguen una lógica estricta de "Si A, entonces B". Si tu arquitectura es rara (y seamos honestos, cada arquitectura empresarial es rara), el script se rompe o produce código que tienes que reescribir.&lt;/p&gt;

&lt;p&gt;El servidor MCP expone herramientas que cambian esta dinámica:&lt;/p&gt;

&lt;h3&gt;
  
  
  Herramienta 1: &lt;code&gt;get_best_practices&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;La IA puede obtener las recomendaciones actuales del equipo de Angular. No alucinará que deberías usar &lt;code&gt;SharedModule&lt;/code&gt; en 2025 porque "lo leyó en un blog de 2021". Pregunta al CLI por la verdad fundamental.&lt;/p&gt;

&lt;h3&gt;
  
  
  Herramienta 2: &lt;code&gt;onpush_zoneless_migration&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Esta es la grande para la v21. En lugar de cambiar ciegamente &lt;code&gt;ChangeDetectionStrategy.Default&lt;/code&gt; a &lt;code&gt;OnPush&lt;/code&gt;, la IA utiliza esta herramienta para analizar tu gráfico de dependencias.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;El flujo de trabajo:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tú:&lt;/strong&gt; "Oye, quiero migrar &lt;code&gt;user-profile.ts&lt;/code&gt; a Zoneless. Comprueba si es seguro."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IA (Pensamiento Interno):&lt;/strong&gt; Necesito comprobar el estilo del componente. Llamaré a &lt;code&gt;list_projects&lt;/code&gt; para encontrar la raíz, luego leeré el archivo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IA (Pensamiento Interno):&lt;/strong&gt; Veo una suscripción a Observable en &lt;code&gt;ngOnInit&lt;/code&gt;. Comprobaré &lt;code&gt;get_best_practices&lt;/code&gt; para manejar asincronía en Zoneless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IA (Acción):&lt;/strong&gt; "Detecté una suscripción no gestionada. En Zoneless, esto no activará un renderizado. Recomiendo convertir este observable &lt;code&gt;user$&lt;/code&gt; a una Signal usando &lt;code&gt;toSignal()&lt;/code&gt; antes de cambiar la estrategia."&lt;/p&gt;

&lt;p&gt;No solo aplica una solución; negocia la refactorización contigo basándose en la lógica interna del marco.&lt;/p&gt;

&lt;h3&gt;
  
  
  Herramienta 3: &lt;code&gt;search_documentation&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;La IA no necesita adivinar las firmas de la API. Consulta el índice de documentación local fuera de línea proporcionado por el servidor MCP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escenario del mundo real: La limpieza "Legacy"
&lt;/h2&gt;

&lt;p&gt;Digamos que tienes un componente al estilo Angular 17 usando &lt;code&gt;HttpClientModule&lt;/code&gt; (enfoque obsoleto) y RxJS para estado simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt a Cursor (con MCP activo):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"Refactoriza &lt;code&gt;dashboard.component.ts&lt;/code&gt; para alinearlo con las mejores prácticas de Angular 21. Usa la herramienta &lt;code&gt;get_best_practices&lt;/code&gt; para verificar tu plan primero."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué sucede:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;La IA llama a &lt;code&gt;get_best_practices&lt;/code&gt; y aprende que &lt;code&gt;standalone: true&lt;/code&gt;, &lt;code&gt;inject()&lt;/code&gt; y Signals son el estándar.&lt;/li&gt;
&lt;li&gt;Llama a &lt;code&gt;modernize&lt;/code&gt; (una herramienta experimental en v21) para ejecutar los esquemáticos estándar.&lt;/li&gt;
&lt;li&gt;Limpia manualmente los restos: convirtiendo &lt;code&gt;constructor(private http: HttpClient)&lt;/code&gt; a &lt;code&gt;private http = inject(HttpClient)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Convierte tu estado &lt;code&gt;BehaviorSubject&lt;/code&gt; a &lt;code&gt;signal&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El resultado es código que parece escrito en v21, no solo parcheado para ejecutarse en v21.&lt;/p&gt;

&lt;h2&gt;
  
  
  El futuro: Mantenimiento continuo
&lt;/h2&gt;

&lt;p&gt;Este lanzamiento señala un cambio en cómo Google ve el CLI. Ya no es solo una herramienta de construcción; es una interfaz para agentes.&lt;/p&gt;

&lt;p&gt;En el futuro cercano, probablemente no "pararemos el desarrollo" para actualizar. Tendremos un agente en segundo plano ejecutándose vía MCP que abre PRs:&lt;/p&gt;

&lt;p&gt;"Noté que usaste un &lt;code&gt;ControlValueAccessor&lt;/code&gt; aquí. He creado un PR para refactorizar esto a la nueva API de entrada de Signal Forms."&lt;/p&gt;

&lt;p&gt;"Angular v22 acaba de salir. He actualizado tu &lt;code&gt;angular.json&lt;/code&gt; y verificado tus pruebas vía vitest."&lt;/p&gt;

&lt;h2&gt;
  
  
  Resumen: No actualices solo.
&lt;/h2&gt;

&lt;p&gt;Si te estás moviendo a Angular 21, no ejecutes simplemente &lt;code&gt;ng update&lt;/code&gt; y pelees con los errores de compilación manualmente.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instala el servidor MCP.&lt;/li&gt;
&lt;li&gt;Deja que la IA mapee tu proyecto.&lt;/li&gt;
&lt;li&gt;Pídele que planifique la migración por ti.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El código sigue siendo tu responsabilidad, ¿pero el trabajo pesado? Eso pertenece a la máquina ahora.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>frontend</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Migrando Angular 20 a 21: Guía.</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sat, 13 Dec 2025 07:47:46 +0000</pubDate>
      <link>https://forem.com/angularfirebase/migrando-angular-20-a-21-guia-4ac2</link>
      <guid>https://forem.com/angularfirebase/migrando-angular-20-a-21-guia-4ac2</guid>
      <description>&lt;p&gt;Una guía sin rodeos para actualizar de Angular 20 a 21. Cubre la eliminación de Karma, el nuevo modo Zoneless por defecto, HttpClient automático y cómo arreglar tus compilaciones rotas.&lt;/p&gt;

&lt;p&gt;Si pensabas que Angular 20 fue un gran cambio, bienvenido a Angular 21.&lt;/p&gt;

&lt;p&gt;Mientras la versión 20 trataba de estabilizar Signals, la versión 21 trata de mejorar la experiencia del desarrollador. Angular ha cambiado fundamentalmente: &lt;code&gt;zone.js&lt;/code&gt; es opcional, Karma está muerto y RxJS parece ser reemplazado lentamente.&lt;/p&gt;

&lt;p&gt;Esto no es solo una actualización; se siente como todo un ecosistema nuevo. Aquí está lo que se va a romper y cómo arreglarlo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lo crítico que detienen todo
&lt;/h2&gt;

&lt;p&gt;Antes de ejecutar &lt;code&gt;ng update&lt;/code&gt;, ten en cuenta que tu compilación probablemente fallará si dependes de estos patrones heredados.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. El Evento de Extinción de Karma (Vitest es el predeterminado)
&lt;/h3&gt;

&lt;p&gt;El choque más inmediato para muchos equipos será &lt;code&gt;ng test&lt;/code&gt;. Angular 21 ha cambiado oficialmente Karma por Vitest como el ejecutor de pruebas predeterminado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué se rompe:&lt;/strong&gt; Si tienes un &lt;code&gt;karma.conf.js&lt;/code&gt; personalizado o dependes de complementos/reportadores específicos de Karma, tu suite de pruebas es ahora código heredado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La solución:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Nuevos proyectos:&lt;/strong&gt; Obtienes Vitest desde el principio. Es más rápido, más limpio y usa Vite.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Proyectos existentes:&lt;/strong&gt; No estás obligado a cambiar inmediatamente, pero el final está cerca. El CLI te insistirá.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Migración:&lt;/strong&gt; Ejecuta el s &lt;code&gt;ng generate @angular/core:karma-to-vitest&lt;/code&gt; para intentar una auto-migración. Es notablemente bueno convirtiendo configuraciones estándar, pero los trucos personalizados de Webpack en tu configuración de pruebas necesitarán reescritura manual para Vite.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. HttpClient está "simplemente ahí".
&lt;/h3&gt;

&lt;p&gt;¿Recuerdas añadir &lt;code&gt;provideHttpClient()&lt;/code&gt; a tu &lt;code&gt;app.config.ts&lt;/code&gt; o importar &lt;code&gt;HttpClientModule&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;El cambio:&lt;/strong&gt; &lt;code&gt;HttpClient&lt;/code&gt; ahora se inyecta por defecto en el inyector raíz.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué se rompe:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Si tienes pruebas que simulan &lt;code&gt;HttpClient&lt;/code&gt; esperando que no esté allí, podrían fallar.&lt;/li&gt;
&lt;li&gt;  Si dependes de &lt;code&gt;HttpClientModule&lt;/code&gt; para un orden complejo de interceptores en una aplicación mixta NgModule/Standalone, podrías ver cambios sutiles de comportamiento.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;La solución&lt;/strong&gt;: Elimina las llamadas explícitas a &lt;code&gt;provideHttpClient()&lt;/code&gt; a menos que estés pasando opciones de configuración (como &lt;code&gt;withInterceptors&lt;/code&gt; o &lt;code&gt;withFetch&lt;/code&gt;). Limpia tu configuración, pero comprueba el orden de ejecución de tus interceptores.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. zone.js se ha ido (para nuevas apps).
&lt;/h3&gt;

&lt;p&gt;Las nuevas aplicaciones generadas con &lt;code&gt;ng new&lt;/code&gt; excluirán &lt;code&gt;zone.js&lt;/code&gt; por defecto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Qué se rompe:&lt;/strong&gt; Nada para las aplicaciones existentes (todavía). Tu &lt;code&gt;polyfils.ts&lt;/code&gt; seguirá importando Zone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La advertencia:&lt;/strong&gt; Si copias y pegas código de un tutorial nuevo de v21 en tu aplicación v20 existente, podría asumir un comportamiento Zoneless (usando menos &lt;code&gt;ChangeDetectorRef&lt;/code&gt;, confiando en Signals). Si mezclas los dos paradigmas sin entenderlos, obtendrás errores "changed after checked" o vistas que no se actualizan.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ Las nuevas características
&lt;/h2&gt;

&lt;p&gt;Una vez que arregles la compilación, la v21 ofrece algunas mejoras increíbles en la experiencia de desarrollo (DX).&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Signal Forms (Experimental pero estable)
&lt;/h3&gt;

&lt;p&gt;Esta es la característica que hemos estado esperando. No más espagueti de &lt;code&gt;valueChanges.pipe(...)&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/forms/signals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Definir un modelo de formulario reactivo&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loginForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Validators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// ¡Accede a los valores directamente como signals!&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loginForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Por qué usarlo:&lt;/strong&gt; Es seguro en cuanto a tipos por defecto y no requiere maestría en RxJS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Estado:&lt;/strong&gt; Experimental. Úsalo para nuevas características, pero tal vez no reescribas tu flujo de pago todavía.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Angular Aria (Developer Preview)
&lt;/h3&gt;

&lt;p&gt;Una nueva biblioteca de primitivas "headless" para accesibilidad.&lt;/p&gt;

&lt;p&gt;En lugar de pelear con &lt;code&gt;aria-expanded&lt;/code&gt; y &lt;code&gt;role="button"&lt;/code&gt;, usas directivas que manejan la lógica de accesibilidad mientras tú manejas el CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Maneja navegación por teclado, foco y roles ARIA automáticamente --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;ariaMenu&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;ariaMenuItem&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Opción 1&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;ariaMenuItem&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Opción 2&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Regex en plantillas
&lt;/h3&gt;

&lt;p&gt;Pequeño pero poderoso. Finalmente, puedes usar literales de expresiones regulares en plantillas, perfecto para la lógica &lt;code&gt;@if&lt;/code&gt; sin crear una función auxiliar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@if (email() | match: /@company\.com$/) {
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"badge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Empleado&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛠️ La lista de verificación de actualización
&lt;/h2&gt;

&lt;p&gt;¿Listo para saltar? Sigue este orden para minimizar el dolor.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Copia de seguridad:&lt;/strong&gt; Haz commit de todo. En serio.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Actualizar el CLI Global:&lt;/strong&gt;&lt;br&gt;
Actualizar Angular generalmente implica dos partes: el CLI global y las dependencias locales del proyecto. Asegúrate de que tu CLI global esté actualizado primero (podrías necesitar sudo o privilegios de administrador).&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Opcional: Desinstalar la versión global antigua primero para evitar conflictos&lt;/span&gt;
npm uninstall &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli

&lt;span class="c"&gt;# Verificar la caché de npm&lt;/span&gt;
npm cache verify

&lt;span class="c"&gt;# Instalar la última versión global del CLI&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Actualizar proyecto local:&lt;/strong&gt;&lt;br&gt;
Ahora actualiza las dependencias locales de tu proyecto:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli@21 @angular/core@21
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ejecutar los diagnósticos:&lt;/strong&gt;&lt;br&gt;
Angular 21 incluye diagnósticos más inteligentes. Presta atención a las advertencias sobre &lt;code&gt;ngClass&lt;/code&gt; (obsoleto a favor de &lt;code&gt;[class.my-class]&lt;/code&gt;) y oportunidades de migración standalone.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Comprobar tus pruebas:&lt;/strong&gt;&lt;br&gt;
Ejecuta &lt;code&gt;ng test&lt;/code&gt;. Si explota, decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ruta A:&lt;/strong&gt; Mantener Karma (añadir &lt;code&gt;@angular/build:karma&lt;/code&gt; manualmente si se eliminó).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ruta B:&lt;/strong&gt; Migrar a Vitest (recomendado).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Opcional: Ir zoneless:&lt;/strong&gt;&lt;br&gt;
Si te sientes valiente, ejecuta la migración experimental:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:zoneless-migration
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Nota&lt;br&gt;
Esto es territorio "Agéntico". Mira nuestra &lt;a href="https://dev.to/angularfirebase/angular-21-y-mcp-el-fin-de-las-migraciones-manuales-4ocn"&gt;Guía MCP&lt;/a&gt; para saber cómo dejar que la IA maneje esta refactorización compleja.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Resumen
&lt;/h2&gt;

&lt;p&gt;Angular 21 es el lanzamiento de "borrón y cuenta nueva". Se deshace del peso de la última década (Zone, Karma, Modules) para competir con marcos modernos como Svelte y Solid.&lt;/p&gt;

&lt;p&gt;La actualización puede ser irregular debido a los cambios en las pruebas, pero el destino —un marco más rápido, más simple e impulsado por signals— vale absolutamente la pena.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>spanish</category>
    </item>
    <item>
      <title>El cambio declarativo de Angular</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sun, 19 Oct 2025 09:02:30 +0000</pubDate>
      <link>https://forem.com/angularfirebase/el-cambio-declarativo-de-angular-27ai</link>
      <guid>https://forem.com/angularfirebase/el-cambio-declarativo-de-angular-27ai</guid>
      <description>&lt;h2&gt;
  
  
  Cómo la Nueva Estructura de Carpetas lo Cambia Todo
&lt;/h2&gt;

&lt;p&gt;Si no has actualizado a la versión 20, la primera y segunda parte de esta guía te pueden ayudar a comprender qué cambia y actualizar. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parte 1: La actualización en sí misma 🛠️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Primero, resolvamos lo básico. Antes de ejecutar cualquier comando, asegúrate de que tu entorno esté listo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerrequisitos&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt;: v20.11.1 o posterior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt;: v5.8 o posterior.&lt;/li&gt;
&lt;li&gt;**Copia de seguridad del proyecto: Asegúrate de confirmar todos tus cambios actuales en Git. En serio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;El Comando de Actualización&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Una vez que hayas confirmado tu versión de Node.js, ejecuta el comando que se ajuste a tu proyecto.&lt;/p&gt;

&lt;p&gt;Para un proyecto estándar de Angular:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli @angular/core 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si utilizas Angular Material:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli @angular/core @angular/material 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El proceso de actualización se ejecutará, pero es probable que te encuentres con tu primer obstáculo de inmediato.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Parte 2: Lo que se rompe inmediatamente *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A diferencia de las actualizaciones anteriores, Angular 20 introduce un cambio significativo que detendrá tu compilación.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. La Historia Completa Detrás de la Eliminación de Karma&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lo primero que notarás es que &lt;code&gt;ng test&lt;/code&gt; fallará. Esto no es solo un error; es un cambio fundamental en las herramientas de compilación de Angular. Con Angular 20, el paquete de compilación predeterminado cambia de &lt;code&gt;@angular-devkit/build-angular&lt;/code&gt; al nuevo &lt;code&gt;@angular/build&lt;/code&gt;. Este nuevo paquete &lt;strong&gt;no incluye Karma&lt;/strong&gt;. El ecosistema web ha avanzado hacia ejecutores de pruebas más rápidos y modernos como &lt;strong&gt;Vitest&lt;/strong&gt; y &lt;strong&gt;Jest&lt;/strong&gt;, y Karma se había convertido en un cuello de botella.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;La solución temporal:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para que tus pruebas se ejecuten sin migrar todo hoy, debes reinstalar manualmente la antigua herramienta de compilación. Esto obliga a la CLI a usar el antiguo compilador que aún es compatible con Karma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @angular-devkit/build-angular &lt;span class="nt"&gt;--save-dev&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este es un puente de compatibilidad. El mensaje del equipo de Angular es claro: comienza a planificar tu migración a Jest o Vitest pronto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. browserslist y soporte de navegadores&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aquí hay un detalle menor que podría sorprenderte. Angular 20 &lt;strong&gt;oficialmente ya no es compatible con Opera&lt;/strong&gt;. Si tienes "Opera" listado en tu archivo &lt;code&gt;.browserslistrc&lt;/code&gt;, tu compilación puede fallar o arrojar advertencias. Quítalo para resolver el problema.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Parte 3: La Nueva Arquitectura *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Más allá de los cambios importantes, Angular 20 impulsa una arquitectura más moderna, explícita y escalable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Componentes standalone por defecto.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Los nuevos proyectos generados con &lt;code&gt;ng new&lt;/code&gt; ahora son &lt;em&gt;standalone&lt;/em&gt; (independientes) por defecto. Esto marca un cambio arquitectónico fundamental que se aleja de los NgModules. Al listar las dependencias directamente en el &lt;em&gt;array&lt;/em&gt; &lt;code&gt;imports&lt;/code&gt; de un componente, cada componente se vuelve autocontenido.&lt;/p&gt;

&lt;p&gt;¿Qué implica este cambio?:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arquitectura más clara y definida&lt;/strong&gt;: Sabes exactamente lo que necesita cada componente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mejora el *tree-shaking&lt;/strong&gt;*: Conduce a paquetes más pequeños y optimizados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para migrar tus proyectos existentes, puedes ejecutar el &lt;em&gt;schematic&lt;/em&gt; de migración &lt;em&gt;standalone&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:standalone 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Una estructura de carpetas que cuenta una historia&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Una buena estructura de carpetas no solo contiene archivos, sino que te dice lo que hace la aplicación. Vale la pena hacer énfasis en la guía de estilo oficial de Angular, ya que sus recomendaciones se basan en años de experiencia comunitaria. Esta filosofía, detallada en su &lt;a href="https://angular.dev/reference/configs/file-structure" rel="noopener noreferrer"&gt;página de referencia de estructura de archivos&lt;/a&gt;, a menudo se resume con el acrónimo &lt;strong&gt;LIFT&lt;/strong&gt; (por sus siglas en inglés: Localizar, Identificar, Plano, Tratar de ser DRY):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;L&lt;/strong&gt;ocate (Localiza) tu código fácilmente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I&lt;/strong&gt;dentify (Identifica) lo que hace un archivo de un vistazo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;F&lt;/strong&gt;lat Flat (Plano): Mantén estructura plana tanto como puedas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;T&lt;/strong&gt;ry to be DRY: Don't Repeat Yourself (Trata de no repetirte).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La conclusión principal es &lt;strong&gt;organizar por característica, no por tipo&lt;/strong&gt;. En lugar de una carpeta &lt;code&gt;components&lt;/code&gt; y una carpeta &lt;code&gt;services&lt;/code&gt;, crea carpetas para características como &lt;code&gt;user-profile&lt;/code&gt; o &lt;code&gt;product-list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Usemos un ejemplo práctico para una aplicación de comercio electrónico:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src/app/
├── core/
│   ├── auth/          &lt;span class="c"&gt;# Lógica de autenticación usada en todas partes&lt;/span&gt;
│   │   ├── auth-store.ts
│   │   └── auth-interceptor.ts
│   └── layout/        &lt;span class="c"&gt;# El shell de la aplicación: barra de navegación, pie de página&lt;/span&gt;
│       ├── navbar.ts
│       └── footer.ts
│
├── features/
│   ├── products/      &lt;span class="c"&gt;# Todo para navegar por los productos&lt;/span&gt;
│   │   ├── product-list.ts
│   │   ├── product-details.ts
│   │   └── product-search.ts
│   │
│   └── cart/          &lt;span class="c"&gt;# La característica del carrito de compras&lt;/span&gt;
│       ├── cart-store.ts
│       ├── cart-view.ts
│       └── add-to-cart.ts
│
└── shared/            &lt;span class="c"&gt;# Componentes "tontos" reutilizables y utilidades&lt;/span&gt;
    └── ui/
        ├── button.ts
        ├── spinner.ts
        └── price.pipe.ts 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;¿Por qué funciona esto?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;core (Proporcionar una vez):&lt;/strong&gt; Servicios y componentes que la aplicación necesita para ejecutarse, cargados solo una vez (&lt;code&gt;AuthStore&lt;/code&gt;, &lt;code&gt;Navbar&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Features  (Lo que hace tu aplicación):&lt;/strong&gt; El corazón de tu aplicación. Cada carpeta es una característica autocontenida.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;shared (Bloques de construcción reutilizables):&lt;/strong&gt; Componentes "tontos", &lt;em&gt;pipes&lt;/em&gt; y directivas que no saben nada sobre las características en las que se utilizan (&lt;code&gt;Button&lt;/code&gt;,
&lt;code&gt;Spinner&lt;/code&gt;). Son importados por los módulos de características.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;3. La Nueva Convención de Nombres&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Angular 20 introduce una nueva convención oficial de nombres que &lt;strong&gt;elimina los sufijos tradicionales&lt;/strong&gt; como &lt;code&gt;.component.ts&lt;/code&gt; o &lt;code&gt;.service.ts&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Nomenclatura Antigua&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Nueva Nomenclatura&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Intención&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;user-profile.component.ts&lt;/td&gt;
&lt;td&gt;user-profile.ts&lt;/td&gt;
&lt;td&gt;Componente de Interfaz de Usuario&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;auth.service.ts&lt;/td&gt;
&lt;td&gt;auth-store.ts&lt;/td&gt;
&lt;td&gt;Gestión de estado&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;highlight.directive.ts&lt;/td&gt;
&lt;td&gt;highlight.ts&lt;/td&gt;
&lt;td&gt;Directiva&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;user-api.service.ts&lt;/td&gt;
&lt;td&gt;user-api.ts&lt;/td&gt;
&lt;td&gt;Cliente HTTP&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;El objetivo es centrarse en la &lt;strong&gt;intención&lt;/strong&gt; del archivo en lugar de su tipo técnico. Una clase que maneja el estado es un "store" (almacén), y una que realiza peticiones HTTP es una "api". Esto hace que el propósito de tu código sea mucho más claro, especialmente en una estructura de carpetas basada en características.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Parte 4: Las nuevas herramientas y sintaxis *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Finalmente, veamos las nuevas herramientas que mejorarán tu desarrollo diario.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. El flujo de control es más que syntactic sugar (azúcar sintáctico).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;El nuevo bloque &lt;code&gt;@for&lt;/code&gt; reemplaza a &lt;code&gt;*ngFor&lt;/code&gt; y es una mejora importante.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sintaxis antigua:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nx"&gt;ngFor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;let item of items; trackBy: trackItemById&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nueva sintaxis:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;track&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;empty&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;hay&lt;/span&gt; &lt;span class="nx"&gt;elementos&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="nx"&gt;mostrar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mejoras clave:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;track&lt;/code&gt; es &lt;strong&gt;obligatorio&lt;/strong&gt;, lo que impone una mejor práctica de rendimiento que a menudo se olvidaba.&lt;/li&gt;
&lt;li&gt;El bloque &lt;code&gt;@empty&lt;/code&gt; incorporado limpia las plantillas al eliminar la necesidad de un &lt;code&gt;*ngIf&lt;/code&gt; separado.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Puedes usar la CLI para refactorizar automáticamente tus plantillas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:control-flow 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Zoneless: Escapando de la "magia de la detección de cambios".&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aunque todavía es experimental, el camino hacia un Angular sin zonas (&lt;em&gt;zoneless&lt;/em&gt;) se está volviendo más claro. En un mundo sin zonas, la interfaz de usuario solo se actualiza cuando se lo indicas explícitamente.&lt;/p&gt;

&lt;p&gt;Los &lt;strong&gt;signals&lt;/strong&gt; (señales) son la herramienta principal para esto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mySignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta línea le indica directamente a Angular que actualice solo las partes específicas del DOM que dependen de esa señal. Es un enfoque quirúrgico, predecible y de alto rendimiento que elimina la sobrecarga y la imprevisibilidad de Zone.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusión&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Angular 20 es una versión significativa. La actualización requiere intervención manual para las pruebas, pero impulsa el &lt;em&gt;framework&lt;/em&gt; hacia un futuro más moderno, explícito y de alto rendimiento. Al adoptar componentes &lt;em&gt;standalone&lt;/em&gt;, una arquitectura basada en características y el nuevo flujo de control, no solo estás actualizando, sino que estás preparando tu aplicación para la próxima era del desarrollo web.&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>angular</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Angular 20: De la programación imperativa a la creación declarativa de componentes dinámicos</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Thu, 09 Oct 2025 15:20:49 +0000</pubDate>
      <link>https://forem.com/angularfirebase/angular-20-de-la-programacion-imperativa-a-la-creacion-declarativa-de-componentes-dinamicos-42e</link>
      <guid>https://forem.com/angularfirebase/angular-20-de-la-programacion-imperativa-a-la-creacion-declarativa-de-componentes-dinamicos-42e</guid>
      <description>&lt;p&gt;Angular 20 llega con &lt;strong&gt;nuevas y geniales características y mejoras&lt;/strong&gt;. Una de las adiciones más significativas es la simplificación de la creación de componentes dinámicos, que la hace &lt;strong&gt;mucho más limpia, consistente y predecible&lt;/strong&gt;. Esta mejora alinea la sintaxis para componentes dinámicos con la forma en que funcionan los &lt;strong&gt;"enlaces"&lt;/strong&gt; (&lt;code&gt;bindings&lt;/code&gt;) en las plantillas de componentes.&lt;/p&gt;

&lt;p&gt;Anteriormente, la creación de componentes dinámicos se sentía como el complejo proceso de &lt;strong&gt;ensamblar una PC personalizada a partir de piezas dispares y manuales&lt;/strong&gt;: funcional, sí, pero requería que el desarrollador lidiara manualmente con cada cable, cada conexión y cada compatibilidad.  Ahora, Angular 20 te da un panel de control unificado.&lt;/p&gt;

&lt;h2&gt;
  
  
  El laberinto de la construcción manual (Pre-Angular 20)
&lt;/h2&gt;

&lt;p&gt;Antes de Angular 20, trabajar con componentes creados dinámicamente era &lt;strong&gt;engorroso&lt;/strong&gt;. El &lt;strong&gt;"enlace de datos bidireccional"&lt;/strong&gt; (&lt;code&gt;two-way data binding&lt;/code&gt;) era &lt;strong&gt;muy incómodo&lt;/strong&gt;, y no existía un estilo unificado para trabajar con &lt;strong&gt;"entradas"&lt;/strong&gt; (&lt;code&gt;inputs&lt;/code&gt;) y &lt;strong&gt;"salidas"&lt;/strong&gt; (&lt;code&gt;outputs&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Para configurar un componente dinámico, era como si tuviéramos que &lt;strong&gt;conectar cada componente (&lt;code&gt;input&lt;/code&gt;) y cable de salida (&lt;code&gt;output&lt;/code&gt;) de forma individual y a mano&lt;/strong&gt;. Para un hipotético &lt;code&gt;NotificationComponent&lt;/code&gt;, los pasos manuales e imperativos eran:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Conexión manual de componentes&lt;/strong&gt;: Se tenía que usar &lt;code&gt;setInput()&lt;/code&gt; para conectar cada componente (propiedad) por separado.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Preparación manual de los datos&lt;/strong&gt;: Si los datos venían de una &lt;strong&gt;"señal"&lt;/strong&gt; (&lt;code&gt;signal&lt;/code&gt;), debían ser &lt;strong&gt;desenvueltos&lt;/strong&gt; (acceder a su valor) para obtener el valor real y no la función.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Gestión de las conexiones de salida&lt;/strong&gt;: Se requería &lt;strong&gt;suscribirse manualmente a las salidas&lt;/strong&gt; (&lt;code&gt;outputs&lt;/code&gt;), guardando cada suscripción. Era crucial &lt;strong&gt;recordar desconectar estos cables&lt;/strong&gt; (&lt;code&gt;unsubscribe&lt;/code&gt;) para prevenir &lt;strong&gt;fugas de memoria&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Sincronización manual de datos&lt;/strong&gt;: Para que el componente dinámico reaccionara a los cambios en una &lt;code&gt;signal&lt;/code&gt; del padre, era necesario un &lt;strong&gt;"efecto"&lt;/strong&gt; (&lt;code&gt;effect&lt;/code&gt;) para rastrear el cambio y luego &lt;strong&gt;volver a conectar manualmente el cable&lt;/strong&gt; (&lt;code&gt;setInput&lt;/code&gt;) con el nuevo valor.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El código era como un diagrama de cableado muy &lt;strong&gt;imperativo&lt;/strong&gt; y no reactivo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Enfoque anterior (Imperativo)&lt;/span&gt;

&lt;span class="c1"&gt;// Paso 1: Conexión básica de la placa madre&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;componentRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;container&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;createComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NotificationComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Paso 2: Conexión manual de los componentes y datos&lt;/span&gt;
&lt;span class="nx"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alerta de estado&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;priority&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prioritySignal&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// ¡Desenvolver el valor de la signal!&lt;/span&gt;

&lt;span class="c1"&gt;// Paso 3 &amp;amp; 4: Conexión manual de los cables de salida y de sincronización&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscriptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dismissed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Lógica de destrucción manual (desconectar del todo)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Paso 5: Reactividad manual usando efecto&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscriptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Necesario para que el componente se actualice reactivamente&lt;/span&gt;
    &lt;span class="nx"&gt;componentRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;priority&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prioritySignal&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ... Se necesita más código para la sincronización bidireccional y la limpieza de cables.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La forma de acceder a la &lt;strong&gt;salida&lt;/strong&gt; (&lt;code&gt;output&lt;/code&gt;) requería &lt;strong&gt;acceder directamente a la propiedad de la clase&lt;/strong&gt;, lo que no respetaba el &lt;strong&gt;"alias"&lt;/strong&gt; de la salida y era diferente de cómo funciona en las plantillas.&lt;/p&gt;




&lt;h2&gt;
  
  
  El panel de control unificado (Angular 20)
&lt;/h2&gt;

&lt;p&gt;A partir de Angular 20, la configuración de componentes dinámicos se gestiona a través de la nueva propiedad &lt;strong&gt;&lt;code&gt;bindings&lt;/code&gt;&lt;/strong&gt;. Este nuevo enfoque es &lt;strong&gt;declarativo&lt;/strong&gt; y &lt;strong&gt;reactivo&lt;/strong&gt;, y su corazón es la &lt;strong&gt;"referencia del contenedor de vista"&lt;/strong&gt; (&lt;code&gt;ViewContainerRef&lt;/code&gt;), que actúa como el &lt;strong&gt;"socket" principal&lt;/strong&gt; donde se insertará el nuevo componente.&lt;/p&gt;

&lt;h3&gt;
  
  
  El poder de &lt;code&gt;ViewContainerRef&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Una &lt;strong&gt;"referencia del contenedor de vista"&lt;/strong&gt; (&lt;code&gt;ViewContainerRef&lt;/code&gt;) es el &lt;strong&gt;"socket"&lt;/strong&gt; en el chasis de tu PC donde se puede instalar una tarjeta de video o de sonido. Permite crear, eliminar o incluso mover &lt;strong&gt;"tarjetas"&lt;/strong&gt; (&lt;code&gt;views&lt;/code&gt;) dentro de ese contenedor. Para acceder a él, se puede inyectar con &lt;code&gt;inject()&lt;/code&gt; o, para una ubicación específica, usar una referencia de plantilla.&lt;/p&gt;

&lt;p&gt;Para controlar la ubicación exacta de tu componente dinámico, puedes añadir un &lt;code&gt;&amp;lt;ng-container&amp;gt;&lt;/code&gt; en tu plantilla para definir un lugar de inserción:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"createDynamic()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Create Dynamic Component&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ng-container&lt;/span&gt; &lt;span class="na"&gt;#container&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ng-container&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Luego, en el código TypeScript, se accede a esa ubicación específica usando &lt;code&gt;viewChild&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;viewChild&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ViewContainerRef&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora, la creación del componente dinámico con &lt;code&gt;createComponent&lt;/code&gt; se realiza directamente en ese contenedor, asegurando que se renderice en el lugar deseado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuración con &lt;code&gt;bindings&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;La propiedad &lt;code&gt;bindings&lt;/code&gt; permite definir &lt;strong&gt;"enlaces de entrada"&lt;/strong&gt; (&lt;code&gt;input&lt;/code&gt;), &lt;strong&gt;"enlaces de salida"&lt;/strong&gt; (&lt;code&gt;output&lt;/code&gt;) y &lt;strong&gt;"enlaces bidireccionales"&lt;/strong&gt; (&lt;code&gt;two-way bindings&lt;/code&gt;) en un &lt;strong&gt;estilo unificado&lt;/strong&gt;. Esto elimina la necesidad de &lt;code&gt;setInput()&lt;/code&gt; manuales y de suscripciones.&lt;/p&gt;

&lt;p&gt;Aquí está el código completo para un ejemplo práctico, como un &lt;code&gt;DialogComponent&lt;/code&gt;, que ahora se conecta con un solo "conector modular":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Enfoque Angular 20 (Declarativo)&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;outputBinding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;viewChild&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ViewContainerRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DialogComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dialog/dialog.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;button (click)="createDynamic()"&amp;gt;Create Dynamic Component&amp;lt;/button&amp;gt;
    &amp;lt;ng-container #container&amp;gt;&amp;lt;/ng-container&amp;gt;
  `&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;viewChild&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ViewContainerRef&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;createDynamic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;container&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;createComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;DialogComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="c1"&gt;// Conexión del cable de entrada 'isOpen'&lt;/span&gt;
          &lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;isOpen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

          &lt;span class="c1"&gt;// Conexión del cable de entrada 'title'&lt;/span&gt;
          &lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

          &lt;span class="c1"&gt;// Conexión del cable de salida 'onClose' para que se autodesconecte&lt;/span&gt;
          &lt;span class="nf"&gt;outputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;onClose&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;container&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La nueva API &lt;strong&gt;gestiona automáticamente la limpieza de suscripciones&lt;/strong&gt; cuando el componente es destruido, eliminando las &lt;strong&gt;pesadillas de gestión de memoria&lt;/strong&gt; y los cables sueltos.&lt;/p&gt;




&lt;h2&gt;
  
  
  Las tres funciones de enlace en detalle
&lt;/h2&gt;

&lt;p&gt;La API de &lt;strong&gt;"enlaces"&lt;/strong&gt; (&lt;code&gt;bindings&lt;/code&gt;) se compone de tres funciones esenciales que deben importarse desde &lt;code&gt;@angular/core&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;inputBinding()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Esta función se utiliza para conectar las &lt;strong&gt;"entradas"&lt;/strong&gt; (&lt;code&gt;inputs&lt;/code&gt;) del componente:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Argumento&lt;/th&gt;
&lt;th&gt;Propósito&lt;/th&gt;
&lt;th&gt;Detalles&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primer Argumento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;El nombre de la entrada.&lt;/td&gt;
&lt;td&gt;Es el nombre del conector en la tarjeta.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Segundo Argumento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;El valor.&lt;/td&gt;
&lt;td&gt;Es el valor que se transmite. Puede ser un &lt;strong&gt;valor estático&lt;/strong&gt; (un cable con un valor fijo) o una &lt;strong&gt;&lt;code&gt;signal&lt;/code&gt;&lt;/strong&gt; (un cable inteligente que transmite actualizaciones).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cuando se proporciona un &lt;code&gt;signal&lt;/code&gt; directamente, &lt;code&gt;inputBinding&lt;/code&gt; &lt;strong&gt;accede automáticamente al valor de la &lt;code&gt;signal&lt;/code&gt;&lt;/strong&gt; y &lt;strong&gt;rastrea reactivamente los cambios&lt;/strong&gt;, actualizando la entrada del componente sin necesidad de un &lt;code&gt;effect&lt;/code&gt; manual.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplos de &lt;code&gt;inputBinding&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Entrada estática: el valor no cambia después de la creación&lt;/span&gt;
&lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Datos cargados&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="c1"&gt;// Entrada dinámica: automáticamente reactiva a los cambios en la signal&lt;/span&gt;
&lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;priority&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prioritySignal&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="c1"&gt;// Entrada calculada: utiliza una función computada (también reactiva)&lt;/span&gt;
&lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;statusText&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Usuario: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt; - Estado: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;systemStatus&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;code&gt;outputBinding()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Esta función maneja los &lt;strong&gt;"eventos de salida"&lt;/strong&gt; (&lt;code&gt;outputs&lt;/code&gt;) emitidos por el componente dinámico.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Argumento&lt;/th&gt;
&lt;th&gt;Propósito&lt;/th&gt;
&lt;th&gt;Detalles&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primer Argumento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;El nombre de la salida.&lt;/td&gt;
&lt;td&gt;Es el nombre del cable de salida que emite un evento.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Segundo Argumento&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Una función de &lt;strong&gt;"devolución de llamada"&lt;/strong&gt; (&lt;code&gt;callback&lt;/code&gt;).&lt;/td&gt;
&lt;td&gt;Es la lógica que se ejecuta cuando el cable emite un evento.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Se puede especificar el tipo de valor emitido usando un &lt;strong&gt;"tipo genérico"&lt;/strong&gt; (&lt;code&gt;generic type&lt;/code&gt;) para mejorar la seguridad de tipos en TypeScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Salida básica: Maneja el evento de cierre&lt;/span&gt;
&lt;span class="nf"&gt;outputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dismissed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Notificación cerrada!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}),&lt;/span&gt;

&lt;span class="c1"&gt;// Salida con datos y tipado (UserEvent es un tipo genérico)&lt;/span&gt;
&lt;span class="nx"&gt;outputBinding&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userAction&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eventData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;code&gt;twoWayBinding()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Esta es la solución simplificada para el &lt;strong&gt;"enlace de datos bidireccional"&lt;/strong&gt; (&lt;code&gt;two-way data binding&lt;/code&gt;), reemplazando el cableado manual complejo.&lt;/p&gt;

&lt;p&gt;Simplemente se define el nombre de la &lt;strong&gt;"entrada modelo"&lt;/strong&gt; (&lt;code&gt;input model&lt;/code&gt;) y se proporciona la &lt;code&gt;signal&lt;/code&gt; del componente padre que se desea mantener sincronizada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Sincroniza la propiedad 'isUrgent' del componente con 'this.urgentModeSignal' del padre&lt;/span&gt;
&lt;span class="nf"&gt;twoWayBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;isUrgent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;urgentModeSignal&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Angular maneja automáticamente la convención de sufijo &lt;strong&gt;&lt;code&gt;Change&lt;/code&gt;&lt;/strong&gt; (por ejemplo, &lt;code&gt;isUrgent&lt;/code&gt; se empareja con la salida &lt;code&gt;isUrgentChange&lt;/code&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  Directivas aplicadas en tiempo de ejecución
&lt;/h2&gt;

&lt;p&gt;Angular 20 también permite &lt;strong&gt;añadir componentes o características adicionales&lt;/strong&gt; (&lt;code&gt;directives&lt;/code&gt;) al componente creado dinámicamente. Esto se logra mediante la propiedad &lt;code&gt;directives&lt;/code&gt; en la configuración de &lt;code&gt;createComponent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para directivas sencillas, se proporciona el nombre del constructor de la directiva. Para directivas más complejas que requieren configuración, se proporciona un objeto que incluye la clave &lt;code&gt;type&lt;/code&gt; (el constructor de la directiva) y la propiedad &lt;code&gt;bindings&lt;/code&gt; para configurar sus propias entradas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo de directivas de runtime:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Configuraremos un &lt;code&gt;NotificationComponent&lt;/code&gt; con una directiva simple (&lt;code&gt;FocusHighlightDirective&lt;/code&gt;) y una directiva compleja de la librería Material (&lt;code&gt;SnackbarDirective&lt;/code&gt;) para mostrar mensajes de estado al pasar el ratón:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;componentRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;container&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;createComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NotificationComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mueva el ratón para ver más detalles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;directives&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// Directiva simple sin configuración&lt;/span&gt;
    &lt;span class="nx"&gt;FocusHighlightDirective&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="c1"&gt;// Directiva compleja con configuración de entradas&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SnackbarDirective&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// La clase de la directiva&lt;/span&gt;
      &lt;span class="na"&gt;bindings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="c1"&gt;// Configura las entradas de la directiva&lt;/span&gt;
        &lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;snackbarMessage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Información extra al hacer hover&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nf"&gt;inputBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;snackbarPosition&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;right&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta capacidad permite un diseño más modular y una configuración dinámica de la experiencia del usuario.&lt;/p&gt;




&lt;p&gt;En resumen, el nuevo enfoque de Angular 20 hace que la creación de componentes dinámicos sea &lt;strong&gt;más consistente, limpia y legible&lt;/strong&gt;, ya que la sintaxis de &lt;strong&gt;"enlace"&lt;/strong&gt; (&lt;code&gt;binding&lt;/code&gt;) ahora es idéntica a la de las plantillas de Angular, además de ofrecer reactividad incorporada y gestión simplificada de la memoria. Ahora, en lugar de &lt;strong&gt;ensamblar una PC a mano&lt;/strong&gt;, utilizas un &lt;strong&gt;"panel de control" unificado&lt;/strong&gt; para la configuración y conexión de tus componentes.&lt;/p&gt;

&lt;p&gt;Bonus :  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/~/github.com/AntonioCardenas/ngviewcontainerref" rel="noopener noreferrer"&gt;stackblitz&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/AntonioCardenas/ngviewcontainerref" rel="noopener noreferrer"&gt;Github Repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>spanish</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Actualizando a Angular 20</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sat, 28 Jun 2025 10:29:55 +0000</pubDate>
      <link>https://forem.com/angularfirebase/actualizando-a-angular-20-2jj</link>
      <guid>https://forem.com/angularfirebase/actualizando-a-angular-20-2jj</guid>
      <description>&lt;p&gt;Esta es una guía práctica enfocada en lo que realmente importa al actualizar una aplicación del mundo real: qué se rompe, qué facilita tu trabajo y cómo deberías adaptar tu estilo de desarrollo.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. La Historia Completa Detrás de la Eliminación de Karma: Más Allá de una Compilación Rota
&lt;/h3&gt;

&lt;p&gt;El problema inmediato al actualizar es que &lt;code&gt;ng test&lt;/code&gt; fallará. La razón es un cambio fundamental en las herramientas de compilación de Angular.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ya que un framework moderno requiere test runners modernos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  ¿Por qué Angular eliminó Karma?
&lt;/h4&gt;

&lt;p&gt;Con Angular 20, el paquete de compilación predeterminado cambia de &lt;code&gt;@angular-devkit/build-angular&lt;/code&gt; al nuevo &lt;code&gt;@angular/build&lt;/code&gt;. Este nuevo paquete ya no incluye el plugin de Karma utilizado por las configuraciones de prueba heredadas. El ecosistema web ha avanzado hacia test runners más rápidos como Vitest y Jest, que utilizan herramientas modernas como Vite y esbuild. Karma se había convertido en un cuello de botella.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cómo es el nuevo panorama (Vitest/Jest)
&lt;/h4&gt;

&lt;p&gt;El test runner experimental de Angular, ahora impulsado por Vitest, es el futuro. Migrar significa que tus pruebas unitarias se ejecutarán en un entorno rápido y moderno basado en Node.js.&lt;/p&gt;

&lt;h4&gt;
  
  
  La "solución temporal" explicada
&lt;/h4&gt;

&lt;p&gt;Este comando obliga a la CLI a volver al compilador antiguo que todavía soporta Karma. Es un puente de compatibilidad, pero el mensaje es claro: deberías empezar a planificar tu migración a Jest or Vitest pronto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @angular-devkit/build-angular &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Prerrequisitos
&lt;/h3&gt;

&lt;p&gt;Antes de comenzar el proceso de actualización, asegúrate de cumplir con los siguientes requisitos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js:&lt;/strong&gt; Versión &lt;code&gt;20.11.1&lt;/code&gt; o posterior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript:&lt;/strong&gt; Versión &lt;code&gt;5.8&lt;/code&gt; o posterior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copia de seguridad del proyecto:&lt;/strong&gt; Confirma todos los cambios actuales en Git.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. Cómo Actualizar: Comando CLI y Comparación
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Comando de Actualización
&lt;/h4&gt;

&lt;p&gt;Primero, asegúrate de que estás ejecutando Node.js v20.11.1 o posterior.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli @angular/core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si usas Angular Material, inclúyelo en el comando de actualización:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/cli @angular/core @angular/material
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Intervención Manual Requerida
&lt;/h4&gt;

&lt;p&gt;Esto no era necesario en versiones anteriores, pero ahora es &lt;strong&gt;obligatorio&lt;/strong&gt; if you want to keep using Karma. El comando reinstala el compilador antiguo con soporte para Karma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @angular-devkit/build-angular &lt;span class="nt"&gt;--save-dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Comparación con Actualizaciones Anteriores
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;En v19:&lt;/strong&gt; &lt;code&gt;ng update&lt;/code&gt; simplemente funcionaba.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;En v20:&lt;/strong&gt; Debes reinstalar manualmente el compilador antiguo para Karma.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4. Flujo de Control(Control Flow): Más que Syntaxis Decorativo
&lt;/h3&gt;

&lt;p&gt;La nueva sintaxis &lt;code&gt;@for&lt;/code&gt; reemplaza a &lt;code&gt;*ngFor&lt;/code&gt; y es una mejora importante.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sintaxis Antigua:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngFor=&lt;/span&gt;&lt;span class="s"&gt;"let item of items; trackBy: trackItemById"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  {{ item.name }}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sintaxis Nueva:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@for (item of items; track item.id) {
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;{{ item.name }}&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
} @empty {
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;No hay elementos para mostrar.&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Mejoras clave:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;track&lt;/code&gt; ahora es obligatorio, lo que fomenta las mejores prácticas de rendimiento.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@empty&lt;/code&gt; mejora la experiencia del desarrollador (DX) al eliminar la necesidad de un bloque &lt;code&gt;@if&lt;/code&gt; separado para manejar listas vacías.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Migración Automatizada y Rendimiento
&lt;/h4&gt;

&lt;p&gt;Usa la CLI para refactorizar automáticamente las plantillas a la nueva sintaxis de flujo de control, que ofrece mejoras de rendimiento y un código más mantenible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:control-flow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Mejores Prácticas Generales y Migraciones Adicionales
&lt;/h4&gt;

&lt;p&gt;Considera migrar a otras características modernas de Angular junto con la actualización del flujo de control para una aplicación completamente optimizada. Esto puede incluir componentes standalone, signals como inputs y carga diferida (lazy loading) para rutas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:standalone
ng generate @angular/core:inject
ng generate @angular/core:route-lazy-loading
ng generate @angular/core:signal-input-migration
ng generate @angular/core:signal-queries-migration
ng generate @angular/core:output-migration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  5. Standalone por Defecto: Un Cambio Arquitectónico Fundamental
&lt;/h3&gt;

&lt;p&gt;Al listar explícitamente las dependencias usando el array &lt;code&gt;imports&lt;/code&gt; a nivel de componente, cada componente se vuelve autocontenido. Esto clarifica tu arquitectura y mejora significativamente el tree-shaking, resultando en paquetes de aplicación más pequeños.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Adiós Zone.js (Zoneless): Escapando de la "Magia" de la Detección de Cambios
&lt;/h3&gt;

&lt;p&gt;En un mundo sin zone.js, la interfaz de usuario solo se actualiza cuando se lo indicas explícitamente. Los Signals son la herramienta principal para esto. Cuando llamas a &lt;code&gt;mySignal.set()&lt;/code&gt;, le estás diciendo directamente a Angular que actualice solo las partes del DOM que usan ese signal. Es un enfoque quirúrgico, predecible y de alto rendimiento.&lt;/p&gt;




&lt;h3&gt;
  
  
  7. Nueva Convención de Nombres: Por Qué Parece Complicado
&lt;/h3&gt;

&lt;p&gt;Angular 20 introduce una nueva convención de nombres oficial que elimina los sufijos de tipo tradicionales.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nomenclatura Antigua:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="nx"&gt;highlight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;directive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nomenclatura Nueva:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="nx"&gt;highlight&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El nuevo enfoque está en la &lt;strong&gt;intención&lt;/strong&gt; del archivo en lugar de su tipo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;user-api.ts&lt;/code&gt; → Maneja peticiones HTTP&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;auth-store.ts&lt;/code&gt; → Gestiona el estado reactivo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;movie-card.ts&lt;/code&gt;, &lt;code&gt;movie-details.ts&lt;/code&gt; → Componentes de UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Reglas Clave de Nomenclatura:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Usa guiones para nombres de archivo de varias palabras (ej. &lt;code&gt;user-profile.ts&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Haz que el nombre de la clase coincida con el nombre del archivo.&lt;/li&gt;
&lt;li&gt;Mantén el sufijo &lt;code&gt;.spec.ts&lt;/code&gt; para los archivos de prueba.&lt;/li&gt;
&lt;li&gt;Evita nombres genéricos como &lt;code&gt;utils.ts&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Ubica los archivos relacionados en la misma carpeta (co-locate) dentro de una estructura de carpetas basada en funcionalidades.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ejemplo de Estructura de Carpetas Basada en Funcionalidades:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── core/
│   └── auth/
│       ├── auth-store.ts
│       ├── login.ts
│       └── register.ts
└── features/
    └── users/
        ├── user-profile.ts
        ├── user-api.ts
        └── user-settings.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Beneficios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Diffs en Git más limpias al refactorizar.&lt;/li&gt;
&lt;li&gt;Promueve un código orientado a la intención.&lt;/li&gt;
&lt;li&gt;Facilita la incorporación de nuevos desarrolladores.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  8. Detalle Importante: &lt;code&gt;browserslist&lt;/code&gt; y Soporte de Navegadores
&lt;/h3&gt;

&lt;p&gt;Angular 20 ya no soporta oficialmente Opera. Si tienes Opera en tu archivo &lt;code&gt;.browserslistrc&lt;/code&gt;, puede que necesites eliminarlo. Otros navegadores no convencionales también pueden perder soporte, lo que podría provocar advertencias o problemas de compilación.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>frontend</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Novedades en Angular 20</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Sun, 01 Jun 2025 05:08:21 +0000</pubDate>
      <link>https://forem.com/angularfirebase/novedades-en-angular-20-1o4o</link>
      <guid>https://forem.com/angularfirebase/novedades-en-angular-20-1o4o</guid>
      <description>&lt;h2&gt;
  
  
  Angular 20: ¿Qué hay de nuevo?
&lt;/h2&gt;

&lt;p&gt;Ha pasado mucho tiempo y muchas versiones, pero la calidad se mantiene y mejora.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nuevos requisitos: TypeScript v5.8 y Node v20
&lt;/h3&gt;

&lt;p&gt;Angular v20 nos deja claro cuáles son los nuevos requisitos. Ahora &lt;em&gt;tienes&lt;/em&gt; que estar en &lt;strong&gt;TypeScript v5.8&lt;/strong&gt; (que, por cierto, ya era compatible desde v19.2), así que es hora de decir adiós a las versiones más antiguas de TypeScript).&lt;/p&gt;

&lt;p&gt;Y para Node, dale la bienvenida a &lt;strong&gt;Node v20&lt;/strong&gt; como el nuevo mínimo. Angular v19 fue la gira de despedida para Node 18. ¡Es hora de actualizar esos entornos o agregarles, si usas NVM, colegas!&lt;/p&gt;

&lt;h3&gt;
  
  
  Guía de estilo 2025: ¡Una bocanada de aire fresco!
&lt;/h3&gt;

&lt;p&gt;¡La Guía de Estilo de Angular ha recibido una renovación significativa! Muchas recomendaciones se han reducido para centrarse en lo que &lt;em&gt;realmente&lt;/em&gt; importa.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nombres de archivo recortados:&lt;/strong&gt; Olvídate de &lt;code&gt;UserComponent&lt;/code&gt; en &lt;code&gt;user.component.ts&lt;/code&gt;. Ahora es simplemente &lt;code&gt;User&lt;/code&gt; en &lt;code&gt;user.ts&lt;/code&gt;. Lo mismo para directivas, pipes, etc. La CLI ya está aplicando esto para cosas nuevas. ¿Cuánto tardará tu memoria muscular en adaptarse?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Estructura de carpetas más ligera:&lt;/strong&gt; La carpeta &lt;code&gt;app&lt;/code&gt; de nivel superior podría desaparecer pronto (aunque la CLI aún no ha llegado a ese punto).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Visibilidad de propiedades:&lt;/strong&gt; &lt;code&gt;protected&lt;/code&gt; es ahora la forma para las propiedades que solo se usan en tu plantilla, y &lt;code&gt;readonly&lt;/code&gt; para todas esas propiedades inicializadas por Angular (&lt;code&gt;input()&lt;/code&gt;, &lt;code&gt;output()&lt;/code&gt;, etc.). ¡Tiene sentido!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bindings de Clases y Estilos:&lt;/strong&gt; ¡Es oficial! &lt;code&gt;[class.something]&lt;/code&gt; y &lt;code&gt;[style.something]&lt;/code&gt; son los campeones recomendados sobre &lt;code&gt;ngClass&lt;/code&gt; y &lt;code&gt;ngStyle&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esto es un cambio &lt;em&gt;grande&lt;/em&gt;. Los nuevos proyectos lo adoptarán por defecto. ¿Los existentes? Bueno, o migras o te quedas con las viejas costumbres (la CLI ayuda con una configuración para eso, ¡uf!).&lt;/p&gt;

&lt;h3&gt;
  
  
  APIs de Signals: ¡Mayormente Luz Verde y Estables!
&lt;/h3&gt;

&lt;p&gt;¡Las Signals son el futuro, y las APIs se están consolidando! La mayoría ahora son &lt;strong&gt;estables&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;effect()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;toSignal()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;toObservable()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;afterRenderEffect()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;afterNextRender()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;linkedSignal()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PendingTasks&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;¡Ojo con esto!&lt;/strong&gt; &lt;code&gt;afterRender()&lt;/code&gt; ha sido &lt;strong&gt;renombrado a &lt;code&gt;afterEveryRender()&lt;/code&gt;&lt;/strong&gt; y es estable. Crucialmente, el nombre antiguo &lt;em&gt;desapareció&lt;/em&gt; sin migración automática. ¡Uf, eso podría doler!&lt;/p&gt;

&lt;p&gt;Además, &lt;code&gt;TestBed.flushEffects()&lt;/code&gt; (esa API en developer preview un poco escurridiza) está obsoleta. Usa &lt;code&gt;TestBed.tick()&lt;/code&gt; ahora, que ejecuta todo el proceso de sincronización, mucho más cercano al comportamiento real de la aplicación. &lt;code&gt;effect()&lt;/code&gt; perdió su opción &lt;code&gt;forceRoot&lt;/code&gt; (¿alguien la usaba mucho?), y &lt;code&gt;toSignal()&lt;/code&gt; eliminó &lt;code&gt;rejectErrors&lt;/code&gt; (¡bien pensado, mejores prácticas al poder!). &lt;code&gt;pendingUntilEvent()&lt;/code&gt; Todavía está en developer preview, por lo cual puede que tarde un poco en implementarse.&lt;/p&gt;

&lt;h3&gt;
  
  
  Zoneless: ¡Fuera de Experimental, entra en Developer Preview!
&lt;/h3&gt;

&lt;p&gt;Si las signals son el futuro de la reactividad, ¡Zoneless es el futuro de la detección de cambios! Ya no es "experimental"; ahora está oficialmente en &lt;strong&gt;developer preview&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;provideExperimentalZonelessChangeDetection&lt;/code&gt; ahora es simplemente &lt;code&gt;provideZonelessChangeDetection&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;El flag de la CLI &lt;code&gt;--experimental-zoneless&lt;/code&gt; ahora es simplemente &lt;code&gt;--zoneless&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La CLI incluso te preguntará si quieres habilitarlo para nuevos proyectos. ¿Listos para el #NoZone?&lt;/p&gt;

&lt;h3&gt;
  
  
  Que se va, que se queda y que puede romper nuestro código:
&lt;/h3&gt;

&lt;p&gt;Como en toda versión mayor, algunas cosas se desaparecen para bien:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Las directivas &lt;code&gt;ngIf&lt;/code&gt;, &lt;code&gt;ngFor&lt;/code&gt;, &lt;code&gt;ngSwitch&lt;/code&gt; están oficialmente obsoletas.&lt;/strong&gt; El control de flujo incorporado (&lt;code&gt;@if&lt;/code&gt;, &lt;code&gt;@for&lt;/code&gt;, &lt;code&gt;@switch&lt;/code&gt;) es el rey ahora. Empieza a migrar; ¡probablemente desaparecerán en v22! &lt;code&gt;ng update&lt;/code&gt; Te echará una mano.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;fixture.autoDetectChanges(boolean)&lt;/code&gt;: El parámetro booleano ha desaparecido. Simplemente usa &lt;code&gt;fixture.autoDetectChanges()&lt;/code&gt;. ¿Usar &lt;code&gt;fixture.autoDetectChanges(false)&lt;/code&gt; en un test zoneless? Eso ahora lanzará un error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;TestBed.get()&lt;/code&gt;: ¡Finalmente, &lt;em&gt;finalmente&lt;/em&gt; DESAPARECIÓ!&lt;/strong&gt; Estuvo obsoleto desde Angular v9. &lt;code&gt;TestBed.inject()&lt;/code&gt; Es tu amigo (desde hace mucho). Una migración automática se encargará de esto.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enum &lt;code&gt;InjectFlags&lt;/code&gt;: Eliminado. Los objetos de opciones para las APIs de DI (como &lt;code&gt;inject()&lt;/code&gt;) han sido la norma desde v14.1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Token &lt;code&gt;DOCUMENT&lt;/code&gt;: Se movió de &lt;code&gt;@angular/common&lt;/code&gt; a &lt;code&gt;@angular/core&lt;/code&gt;. Una migración actualizará tus imports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;@angular/platform-browser-dynamic&lt;/code&gt;: Obsoleto en favor de &lt;code&gt;@angular/platform-browser&lt;/code&gt;. Tendrás que actualizar manualmente los imports para este por ahora.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;@angular/platform-server/testing&lt;/code&gt;: También obsoleto, sin reemplazo. Las pruebas E2E son ahora la forma recomendada para verificar aplicaciones SSR.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integración con HammerJS: Obsoleta.&lt;/strong&gt; HammerJS no ha visto una actualización en 8 años. Es hora de decir adiós a esas entidades en el framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Atributos &lt;code&gt;ng-reflect-*&lt;/code&gt;: Desaparecen por defecto en modo desarrollo.&lt;/strong&gt; Eran para antiguas DevTools. Si dependías de ellos (¡probablemente no deberías!), puedes rehabilitarlos con &lt;code&gt;provideNgReflectAttributes()&lt;/code&gt;. Pero quizás... ¿Mejor no?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Plantillas: ¡Nuevos trucos bajo la manga!
&lt;/h3&gt;

&lt;p&gt;Tus plantillas se han vuelto un poco más expresivas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exponenciación:&lt;/strong&gt; &lt;code&gt;{{ 2 ** 3 }}&lt;/code&gt; ahora es posible. ¡Por lo que podemos hacer cálculos de manera más fácil!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tagged Template Literals:&lt;/strong&gt; Sí, &lt;code&gt;{{ translate\&lt;/code&gt;app.title&lt;code&gt;}}&lt;/code&gt; está aquí (técnicamente desde v19.2, pero ahora está asentado).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Operador &lt;code&gt;void&lt;/code&gt;:&lt;/strong&gt; Úsalo como &lt;code&gt;&amp;lt;button (click)="void selectUser()"&amp;gt;&lt;/code&gt; para ignorar explícitamente el retorno de una función, especialmente útil para listeners de eventos donde &lt;code&gt;return false&lt;/code&gt; podría prevenir el comportamiento por defecto.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Operador &lt;code&gt;in&lt;/code&gt;:&lt;/strong&gt; Verifica propiedades como &lt;code&gt;@if ('invoicing' in permissions)&lt;/code&gt;. ¡Súper útil!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Diagnósticos extendidos: ¡El compilador te mantiene informado!
&lt;/h3&gt;

&lt;p&gt;Más verificaciones incorporadas para atrapar errores comunes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;missingStructuralDirective&lt;/code&gt;: ¿Usando algo como &lt;code&gt;*ngTemplateOutlet&lt;/code&gt; pero olvidaste importar &lt;code&gt;NgTemplateOutlet&lt;/code&gt;? El compilador ahora te lo hará saber (con &lt;code&gt;strictTemplates&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;uninvokedTrackFunction&lt;/code&gt;: ¿Escribiste &lt;code&gt;@for (user of users; track getUserId)&lt;/code&gt; en lugar de &lt;code&gt;track getUserId(user)&lt;/code&gt;? Recibirás un codazo amistoso.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;unparenthesizedNullishCoalescing&lt;/code&gt;: Mezclar &lt;code&gt;??&lt;/code&gt; con &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; o &lt;code&gt;||&lt;/code&gt; (ej. &lt;code&gt;a ?? b &amp;amp;&amp;amp; c&lt;/code&gt;) ahora requiere paréntesis para mayor claridad, como &lt;code&gt;{{ a ?? (b &amp;amp;&amp;amp; c) }}&lt;/code&gt;. TypeScript hace esto, ¡así que es genial verlo también en las plantillas!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Puedes suprimirlos en &lt;code&gt;tsconfig.json&lt;/code&gt; si &lt;em&gt;de verdad&lt;/em&gt; quieres, pero... ¿Por qué querrías?&lt;/p&gt;

&lt;h3&gt;
  
  
  Chequeo de tipos en host: ¡Ya no más misterios!
&lt;/h3&gt;

&lt;p&gt;Hay una nueva opción de compilador &lt;code&gt;typeCheckHostBindings&lt;/code&gt; (ya en nuevos proyectos CLI). Si usas metadatos de host en decoradores (o &lt;code&gt;@HostBinding&lt;/code&gt;/&lt;code&gt;@HostListener&lt;/code&gt;), el compilador ahora verifica:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Si el objetivo del binding/listener (ej. &lt;code&gt;value&lt;/code&gt; en &lt;code&gt;[value]="value()"&lt;/code&gt;) es realmente válido para el elemento host.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Si la propiedad en tu clase de componente/directiva (ej. &lt;code&gt;value()&lt;/code&gt;) realmente existe.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;¡Esto es brutal para pillar typos y asegurar que tus bindings de host sean legítimos!&lt;/p&gt;

&lt;h3&gt;
  
  
  Manejo de errores: ¡Menos errores que se escapan!
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;provideBrowserGlobalErrorListeners&lt;/code&gt;: Un nuevo provider (agregado por defecto en nuevos proyectos CLI) para registrar listeners de errores globales en el navegador. Atrapa errores que Angular podría pasar por alto.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Los errores en los listeners de eventos ahora se reportan al manejador de errores interno de Angular. Esto significa que podrías ver errores en tests que antes eran silenciosos. Es hora de arreglarlos (o usar &lt;code&gt;rethrowApplicationErrors: false&lt;/code&gt; en &lt;code&gt;configureTestingModule&lt;/code&gt; como último recurso).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Componentes creados dinámicamente: ¡Sube de nivel!
&lt;/h3&gt;

&lt;p&gt;¡&lt;code&gt;createComponent()&lt;/code&gt; (y &lt;code&gt;ViewContainerRef.createComponent&lt;/code&gt;) se volvieron &lt;em&gt;mucho&lt;/em&gt; más geniales en v20! Ahora puedes pasar opciones para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Especificar &lt;code&gt;directives&lt;/code&gt; a aplicar al componente dinámico.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Proveer valores de input usando la nueva función &lt;code&gt;inputBinding()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Declarar two-way bindings con &lt;code&gt;twoWayBinding()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Escuchar outputs con &lt;code&gt;outputBinding()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esto es un gran avance respecto a llamar &lt;code&gt;setInput&lt;/code&gt; después de la primera detección de cambios. ¡Más poder y control! ¿Llegará esto también a &lt;code&gt;TestBed.createComponent()&lt;/code&gt;?&lt;/p&gt;

&lt;h3&gt;
  
  
  Formularios: Aún esperando las señales, pero...
&lt;/h3&gt;

&lt;p&gt;No hay formularios basados en signals &lt;em&gt;todavía&lt;/em&gt; (¡todos estamos al borde del asiento esperando eso!). Pero v20 trae un par de ajustes pequeños pero bienvenidos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;userForm.resetForm(undefined, { emitEvent: false })&lt;/code&gt;: Resetea formularios sin disparar eventos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;markAllAsDirty()&lt;/code&gt;: Finalmente, un método en &lt;code&gt;AbstractControl&lt;/code&gt; para marcar un control y todos sus descendientes como &lt;code&gt;dirty&lt;/code&gt;. ¡A &lt;code&gt;markAllAsTouched()&lt;/code&gt; le faltaba un hermano!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Router: ¡Navegación más fluida a la vista!
&lt;/h3&gt;

&lt;p&gt;Algunas mejoras interesantes para el router:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Opciones de Scroll:&lt;/strong&gt; Pasa opciones nativas de scroll a &lt;code&gt;ViewportScroller.scrollToAnchor()&lt;/code&gt;/&lt;code&gt;scrollToPosition()&lt;/code&gt;. Por ejemplo, &lt;code&gt;behavior: 'smooth'&lt;/code&gt; para ese efecto de scroll elegante.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resolvers con más contexto:&lt;/strong&gt; ¡Los resolvers de rutas hijas ahora pueden acceder a datos resueltos de su ruta padre! &lt;code&gt;route.data.user&lt;/code&gt; del padre estará disponible. ¡Menos gimnasia para obtener datos!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Redirecciones asíncronas:&lt;/strong&gt; La opción &lt;code&gt;redirectTo&lt;/code&gt; en las configuraciones de ruta ahora puede aceptar una función que devuelva una Promesa o un Observable para redirecciones asíncronas. (Técnicamente un breaking change debido a la evolución del tipo de retorno).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Soporte para Custom Elements:&lt;/strong&gt; ¿Escribiendo Web Components? Ahora puedes usar un custom element como host de un &lt;code&gt;RouterLink&lt;/code&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Http: APIs de &lt;code&gt;resource&lt;/code&gt; Evolucionando y &lt;code&gt;keepalive&lt;/code&gt;!
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cambios en API de &lt;code&gt;resource&lt;/code&gt;:&lt;/strong&gt; El parámetro &lt;code&gt;query&lt;/code&gt; de &lt;code&gt;resource()&lt;/code&gt; ahora es &lt;code&gt;params&lt;/code&gt;. Para &lt;code&gt;rxResource()&lt;/code&gt;, &lt;code&gt;loader&lt;/code&gt; ahora es &lt;code&gt;stream&lt;/code&gt;. El método &lt;code&gt;reload&lt;/code&gt; se movió a &lt;code&gt;WritableResource&lt;/code&gt; (solo los recursos mutables pueden recargarse).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Actualizaciones en &lt;code&gt;httpResource&lt;/code&gt;:&lt;/strong&gt; La opción &lt;code&gt;map&lt;/code&gt; ahora es &lt;code&gt;parse&lt;/code&gt;. Puedes especificar el contexto HTTP en las opciones. Y, la petición &lt;em&gt;debe&lt;/em&gt; ser ahora reactiva (ej. &lt;code&gt;httpResource&amp;lt;User[]&amp;gt;(() =&amp;gt; '/users')&lt;/code&gt; en lugar de solo la URL como string).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Soporte &lt;code&gt;keepalive&lt;/code&gt;:&lt;/strong&gt; &lt;code&gt;HttpClient&lt;/code&gt; ahora soporta la opción &lt;code&gt;keepalive&lt;/code&gt; cuando se usa la API Fetch (habilitada con &lt;code&gt;withFetch()&lt;/code&gt;). Las peticiones no se abortarán si la página se descarga. Útil para cosas como analíticas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Perfilación: ¡Mira dónde es afectado el rendimiento de tu app!
&lt;/h3&gt;

&lt;p&gt;Hay una nueva función &lt;code&gt;enableProfiling()&lt;/code&gt; en &lt;code&gt;@angular/core&lt;/code&gt;. Llama a esto, y Angular usará la API de Performance del navegador para etiquetar operaciones del framework (detección de cambios, plantillas, outputs, defer, etc.). Luego, abre las Devtools de Chrome, graba un perfil de rendimiento y mira la pista personalizada "Angular". ¡Por fin, una vista clara del rendimiento interno!&lt;/p&gt;

&lt;h3&gt;
  
  
  Devtools: ¡Mejores perspectivas!
&lt;/h3&gt;

&lt;p&gt;Las Devtools de Angular se están volviendo más inteligentes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Los componentes &lt;code&gt;OnPush&lt;/code&gt; ahora se marcan como tales en el árbol de componentes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Los bloques diferidos (&lt;code&gt;defer&lt;/code&gt;) también se muestran.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;El soporte para Signals está mejorando – ¡pronto deberíamos ver el árbol de signals! Echar un vistazo bajo el capó ahora es más fácil.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SSR: ¡APIs estables y configuración optimizada!
&lt;/h3&gt;

&lt;p&gt;Buenas noticias para el Server-Side Rendering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;¡Las APIs &lt;code&gt;withI18nSupport()&lt;/code&gt; y &lt;code&gt;withIncrementalHydration()&lt;/code&gt; ahora son estables!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;provideServerRendering()&lt;/code&gt; (ahora en &lt;code&gt;@angular/ssr&lt;/code&gt; en lugar de &lt;code&gt;@angular/platform-server&lt;/code&gt;) se combina con &lt;code&gt;provideServerRoutesConfig()&lt;/code&gt; en una única función &lt;code&gt;provideServerRendering(withRoutes(serverRoutes))&lt;/code&gt;. Una migración se encargará de esto.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Las nuevas apps CLI con &lt;code&gt;--ssr&lt;/code&gt; obtienen Express v5 y soporte de enrutamiento en servidor por defecto (la opción &lt;code&gt;--server-routing&lt;/code&gt; ha desaparecido).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Angular CLI: ¡Esto es ENORME!
&lt;/h3&gt;

&lt;p&gt;La CLI vio un &lt;em&gt;montón&lt;/em&gt; de cambios. Prepárense:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nomenclatura actualizada para Guía de estilo 2025:&lt;/strong&gt; Como se mencionó, &lt;code&gt;user.ts&lt;/code&gt; (con clase &lt;code&gt;User&lt;/code&gt;) en lugar de &lt;code&gt;user.component.ts&lt;/code&gt; (clase &lt;code&gt;UserComponent&lt;/code&gt;). Igual para directivas, servicios. Pipes, resolvers, etc. usan guiones en los nombres de archivo (&lt;code&gt;from-now-pipe.ts&lt;/code&gt;). Una migración de &lt;code&gt;angular.json&lt;/code&gt; configura tus proyectos existentes para usar la convención antigua si quieres una transición suave.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuración de TypeScript:&lt;/strong&gt; La opción &lt;code&gt;module&lt;/code&gt; ahora es &lt;code&gt;preserve&lt;/code&gt; (refleja mejor los bundlers modernos). &lt;code&gt;tsconfig.json&lt;/code&gt; Usa un estilo de "solución", referenciando &lt;code&gt;tsconfig.app.json&lt;/code&gt; y &lt;code&gt;tsconfig.spec.json&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;angular.json&lt;/code&gt; simplificado:&lt;/strong&gt; Los nuevos proyectos usan &lt;code&gt;@angular/build&lt;/code&gt; directamente, deshaciéndose de &lt;code&gt;@angular-devkit/build-angular&lt;/code&gt; y sus dependencias transitivas de Webpack. ¡Eso es casi &lt;strong&gt;200 Mb menos&lt;/strong&gt; en &lt;code&gt;node_modules&lt;/code&gt;! Algunas opciones como &lt;code&gt;outputPath&lt;/code&gt; también se eliminan ya que tienen valores por defecto sensatos. ¡Más ligero y potente!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuración de Browserslist:&lt;/strong&gt; Ahora apunta a la base "ampliamente disponible" (navegadores lanzados hace &amp;lt; 30 meses del conjunto principal de Baseline). Soporte de navegadores más consistente y realista.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Importadores de paquetes Sass:&lt;/strong&gt; Ahora puedes usar importadores &lt;code&gt;pkg:&lt;/code&gt;, como &lt;code&gt;@use 'pkg:@angular/material' as mat;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testing Ahead of Time (AoT) y Cobertura de Código para Plantillas:&lt;/strong&gt; Añade &lt;code&gt;"aot": true&lt;/code&gt; a tus opciones de test en &lt;code&gt;angular.json&lt;/code&gt;. ¡Ejecuta tests en el mismo modo que producción! Además, obtienes cobertura de código para las plantillas. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Testing con Vitest (¡experimental!):&lt;/strong&gt; ¡Notición! La CLI ahora soporta ejecutar tests con &lt;strong&gt;Vitest&lt;/strong&gt;. Hay un nuevo builder &lt;code&gt;@angular/build:unit-test&lt;/code&gt;. Karma y Jasmine podrían tener un nuevo retador.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configúralo con &lt;code&gt;"runner": "vitest"&lt;/code&gt;. Necesitarás un &lt;code&gt;"buildTarget"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Por defecto, usa Node con &lt;code&gt;jsdom&lt;/code&gt; (instálalo).&lt;/li&gt;
&lt;li&gt;Actualiza los &lt;code&gt;types&lt;/code&gt; de &lt;code&gt;tsconfig.spec.json&lt;/code&gt; a &lt;code&gt;["vitest/globals"]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modo Navegador:&lt;/strong&gt; ¡Sí! &lt;code&gt;"browsers": ["chromium"]&lt;/code&gt; (o firefox, webkit). Usa Playwright o WebdriverIO (instala uno).&lt;/li&gt;
&lt;li&gt;El modo watch es más rápido (solo ejecuta tests afectados). Las ejecuciones completas podrían ser un poco más lentas que Karma.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--no-watch&lt;/code&gt; A menudo es implícito en CI.&lt;/li&gt;
&lt;li&gt;Nuevo flag &lt;code&gt;--debug&lt;/code&gt; (Vitest + jsdom/Playwright).&lt;/li&gt;
&lt;li&gt;Limitaciones: Aún no hay archivo de configuración de Vitest personalizado. Pero la opción &lt;code&gt;providersFile&lt;/code&gt; te permite configurar cosas como testing zoneless. Reportes y exclusiones de cobertura están en &lt;code&gt;angular.json&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Carpetas de Workspace automáticas en Chrome:&lt;/strong&gt; ¡El servidor de desarrollo Vite ahora ayuda a las Devtools de Chrome a mapear los archivos de tu proyecto, permitiendo edición directa desde Devtools que se guarda en tu disco! Habilítalo en los flags de Chrome.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sourcemaps sin fuentes:&lt;/strong&gt; Genera sourcemaps &lt;em&gt;sin&lt;/em&gt; incrustar el código fuente original (&lt;code&gt;"sourcesContent": false&lt;/code&gt;). Genial para reportar errores en producción sin exponer todo tu código.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  ¡Angular y su futuro junto a la IA!
&lt;/h3&gt;

&lt;p&gt;Angular se posiciona para facilitar el desarrollo de aplicaciones con capacidades de IA generativa:&lt;/p&gt;

&lt;p&gt;Archivo: &lt;code&gt;llms.txt&lt;/code&gt; Se mantiene un archivo &lt;code&gt;llms.txt&lt;/code&gt;en el repositorio de Angular. Este archivo ayuda a los grandes modelos de lenguaje (LLMs) a descubrir la documentación y los ejemplos de código más recientes y correctos de Angular, para que generen código más moderno y preciso, evitando problemas con APIs o sintaxis obsoletas.&lt;/p&gt;

&lt;p&gt;Guías y recursos: Se están proporcionando guías y recursos, angular.dev/ai incluyendo ejemplos y live streams que muestran cómo integrar Angular con herramientas como Genkit y Vertex AI de Google Cloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  Qué podríamos llegar a ver en Angular v21
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Componentes sin selector:&lt;/strong&gt; Imagina esto:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user/user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// El import de TS aún es necesario&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;User [name]="name()" (selected)="selectUser()" /&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;// ¡NO se necesita el array 'imports' de Angular para User!&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;¡Componentes usados por su nombre de clase directamente en las plantillas! Las directivas podrían usar un prefijo &lt;code&gt;@&lt;/code&gt; (ej. &lt;code&gt;&amp;lt;User @CdkDrag /&amp;gt;&lt;/code&gt;). Los pipes también por nombre de clase (&lt;code&gt;{{ date | FromNowPipe }}&lt;/code&gt;). La sintaxis está LEJOS de ser final, pero el trabajo en el compilador ha comenzado. ¿Alucinante, no? ¡Esto podría ser revolucionario! Debería llegar un RFC.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Formularios con Signals (¿La Tercera Vía?):&lt;/strong&gt; ¡Prepárense para una posible nueva forma de hacer formularios, separada de template-driven y reactive!&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// PROTOTIPO MUY TEMPRANO - ¡NO USAR AÚN!&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user-form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;FieldDirective&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="c1"&gt;// Nueva directiva&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;form&amp;gt;
      &amp;lt;label&amp;gt;Username: &amp;lt;input [field]="userForm.username" /&amp;gt;&amp;lt;/label&amp;gt;
      &amp;lt;label&amp;gt;Name: &amp;lt;input [field]="userForm.name" /&amp;gt;&amp;lt;/label&amp;gt;
    &amp;lt;/form&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserFormComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;userModel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserModel&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;userForm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Field&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="c1"&gt;// nueva función form()&lt;/span&gt;
    &lt;span class="nx"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// datos a editar&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FieldPath&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// esquema para comportamiento dinámico y validación&lt;/span&gt;
      &lt;span class="nf"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No se puede cambiar el nombre de usuario&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userPath&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Debe ser mayor de 18&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Una nueva función &lt;code&gt;form()&lt;/code&gt; y clase &lt;code&gt;Field&lt;/code&gt; para manejar el estado del formulario con signals. ¡Echa un vistazo al design doc si tienes curiosidad, o espera al RFC!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>angular</category>
      <category>spanish</category>
    </item>
    <item>
      <title>El futuro del FrontEnd se escribe… con prompts.</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Wed, 26 Mar 2025 09:13:38 +0000</pubDate>
      <link>https://forem.com/angularfirebase/el-futuro-del-frontend-se-escribe-con-prompts-1f42</link>
      <guid>https://forem.com/angularfirebase/el-futuro-del-frontend-se-escribe-con-prompts-1f42</guid>
      <description>&lt;p&gt;Como sabrán, después de varias iteraciones, v0 ya no solo centra divs.&lt;br&gt;
Ahora plantea una pregunta que incomoda a más de uno:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;¿Hasta qué punto la inteligencia artificial puede - o debe - reemplazar el trabajo de un desarrollador frontend?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  ¿Qué es v0?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://v0.dev" rel="noopener noreferrer"&gt;v0.dev&lt;/a&gt; es una plataforma desarrollada por Vercel que permite generar componentes completos de frontend a partir de descripciones en lenguaje natural. Es una especie de &lt;em&gt;copiloto visual&lt;/em&gt; que, combinando diseño e implementación, devuelve código limpio usando React, Tailwind y otros stacks modernos.&lt;/p&gt;

&lt;p&gt;Lo que diferencia a v0 de otros generadores es su precisión semántica. Entiende el contexto del pedido, ofrece estructuras coherentes y propone soluciones visualmente bien diseñadas.&lt;/p&gt;

&lt;p&gt;No genera "código al azar"; genera componentes útiles, ajustados a lo que el prompt sugiere y a cómo está escrita la petición.&lt;/p&gt;

&lt;p&gt;Hace algún tiempo se filtró el prompt que utiliza v0 de Vercel para construir interfaces a partir de texto plano. Puedes dar un vistazo &lt;a href="https://github.com/x1xhlol/system-prompts-and-models-of-ai-tools/tree/main" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Aunque la noticia generó ruido, también dejó al descubierto lo que realmente hace potente a esta herramienta: el contexto.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es un prompt?
&lt;/h2&gt;

&lt;p&gt;Un &lt;strong&gt;prompt&lt;/strong&gt; es la instrucción que se le da a un modelo de lenguaje para ejecutar una tarea.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Un formulario de registro con validación, modo oscuro y diseño mobile first."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;El poder del prompt no solo está en lo que se pide, sino en &lt;strong&gt;cómo se pide&lt;/strong&gt;. Lenguaje claro, intenciones explícitas y contexto bien delimitado son claves para obtener resultados útiles.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué es el contexto?
&lt;/h2&gt;

&lt;p&gt;En términos técnicos, el &lt;strong&gt;contexto&lt;/strong&gt; es la información adicional que acompaña al prompt y que permite al modelo "entender" de forma más precisa lo que se espera.&lt;/p&gt;

&lt;p&gt;Puede incluir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;El stack deseado (React, Next.js, Tailwind)&lt;/li&gt;
&lt;li&gt;Consideraciones de accesibilidad&lt;/li&gt;
&lt;li&gt;Comportamiento esperado del componente&lt;/li&gt;
&lt;li&gt;Restricciones técnicas o de diseño&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;v0 utiliza un sistema avanzado de &lt;em&gt;prompt engineering&lt;/em&gt; con contexto enriquecido, lo que le permite generar código funcional y relevante para el entorno del proyecto.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Vibe Coding?
&lt;/h2&gt;

&lt;p&gt;El concepto de &lt;strong&gt;vibe coding&lt;/strong&gt; se refiere a una nueva forma de programar guiada más por intención y energía creativa que por la escritura manual de cada línea de código.&lt;/p&gt;

&lt;p&gt;Con herramientas como v0, la experiencia de desarrollo empieza a parecerse más a &lt;em&gt;componer música&lt;/em&gt; que a escribir código.&lt;/p&gt;

&lt;p&gt;El flujo cambia: se convierte en una colaboración entre humano e IA, donde la intuición y el criterio técnico siguen siendo esenciales.&lt;/p&gt;

&lt;p&gt;Y v0 no está solo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cursor&lt;/strong&gt; transforma Visual Studio Code en un entorno conversacional, permitiéndote editar, navegar y escribir código directamente con inteligencia artificial.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude&lt;/strong&gt; permite razonar sobre estructuras complejas y refactorizaciones de alto nivel, muy útil para tareas más abstractas del frontend como diseño de arquitectura.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot&lt;/strong&gt; se mantiene como asistente de línea, recomendando &lt;em&gt;snippets&lt;/em&gt; y completando código mientras escribes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Todas estas herramientas forman parte del nuevo entorno de desarrollo: uno donde el ingenio humano y la eficiencia algorítmica se encuentran en el centro del workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿El fin del FrontEnd Dev?
&lt;/h2&gt;

&lt;p&gt;Personalmente, el enfoque que más me gusta acerca de la inteligencia artificial es el de &lt;strong&gt;aumentar capacidades&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Automatizar sin entender lo que se está haciendo puede ser una trampa peligrosa, generando más deuda técnica que valor real.&lt;/p&gt;

&lt;p&gt;v0 no reemplaza al frontend developer, pero sí le exige evolucionar. El rol se mueve de implementador a &lt;strong&gt;curador, arquitecto y estratega de interfaz&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Saber escribir un buen prompt, entender el contexto del proyecto así como su lógica, probar su seguridad, validar accesibilidad, resolver errores generados por implementaciones de la IA, optimizar rendimiento… Todo eso sigue siendo parte del trabajo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;La inteligencia artificial no elimina el desarrollo frontend. Lo transforma.&lt;br&gt;
Y quienes entiendan esa transformación podrán liderarla en lugar de resistirla.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>spanish</category>
      <category>ai</category>
      <category>v0</category>
      <category>vibecoding</category>
    </item>
    <item>
      <title>Angular 19 httpResource</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Tue, 18 Mar 2025 10:52:24 +0000</pubDate>
      <link>https://forem.com/angularfirebase/angular-19-httpresource-3950</link>
      <guid>https://forem.com/angularfirebase/angular-19-httpresource-3950</guid>
      <description>&lt;p&gt;Llamadas a API basadas en signals&lt;/p&gt;

&lt;p&gt;A partir de Angular v19.2, podemos comenzar a olvidarnos de manejar llamadas a API de manera manual gracias a la nueva primitiva de Angular. &lt;code&gt;httpResource&lt;/code&gt; la que nos permite de manera reactiva obtener datos, haciendo un llamado a nuestra API de preferencia cada vez que el valor cambie. &lt;/p&gt;

&lt;h2&gt;
  
  
  Características principales:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Reactividad automática:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El recurso generado por &lt;code&gt;httpResource&lt;/code&gt; observa señales y automáticamente vuelve a realizar solicitudes HTTP cada vez que las dependencias reactivas cambian.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estado por defecto:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Permite establecer valores predeterminados mediante la propiedad &lt;code&gt;defaultValue&lt;/code&gt;, asegurando una respuesta coherente en situaciones iniciales, estados de carga o errores en las solicitudes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validación y transformación de datos:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La opción &lt;code&gt;parse&lt;/code&gt; facilita la validación y transformación automática de las respuestas HTTP, mejorando la seguridad de tipos y garantizando la integridad de los datos recibidos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ventajas frente al enfoque tradicional:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Reducción significativa de código: Elimina la necesidad de gestionar manualmente suscripciones, reduciendo errores como memory leaks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Actualización automática del estado: Al depender directamente de Signals, los datos se actualizan automáticamente según los cambios en el estado reactivo de la aplicación, eliminando tareas manuales.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mayor seguridad: Promueve un desarrollo robusto mediante validación automática y estricta gestión del estado en todas las fases del ciclo de vida del dato.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Actualmente, esta API se encuentra en fase experimental, por lo que se recomienda seguir su evolución antes de implementarla en entornos de producción críticos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ejemplo de uso e implementación:
&lt;/h2&gt;

&lt;p&gt;Anteriormente debíamos recurrir a RxJS para suscribirnos y desuscribirnos cada que hacíamos una llamada de API, lo cual en ciertas ocasiones contribuía a los famosos memory leaks porque si olvidábamos desuscribirnos.&lt;/p&gt;




&lt;p&gt;Para implementarlo, deberemos comenzar creando una interfaz (interface) definiendo la estructura de nuestro personaje con datos como ser el id, el nombre, la imagen, etc., etc.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Ahora implementamos httpResource en nuestro componente. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;characterResource es un httpResourceRef que devuelve los datos del personaje desde el API; defaultValue se encarga de que characterResource tenga una estructura definida, incluso antes de que los datos sean cargados.&lt;/p&gt;

&lt;p&gt;characterId es un signal que representa el número del personaje que se está mostrando. Cambiar este valor acciona httpResource para obtener la data del personaje seleccionado.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Pero, ¿qué pasa si queremos usar POST, PUT, DELETE?&lt;/p&gt;

&lt;p&gt;Solo debemos cambiar el método (method) y su correspondiente body junto a los params.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;usersResource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;httpResource&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;RickCharacter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;per_page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En el siguiente artículo cubriré aspectos más avanzados como &lt;code&gt;headers&lt;/code&gt; &lt;code&gt;params&lt;/code&gt;,etc. pero por ahora puedes ver todo el código funcional en el siguiente:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ejemplo:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/stackblitz-angularhttpresource?embed=1&amp;amp;file=src%2Frickandmoty.component.ts" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>typescript</category>
      <category>spanish</category>
    </item>
    <item>
      <title>Proyecto Fugu: Revolucionando las aplicaciones web progresivas (PWA)</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Mon, 25 Nov 2024 14:00:00 +0000</pubDate>
      <link>https://forem.com/angularfirebase/proyecto-fugu-revolucionando-las-aplicaciones-web-progresivas-pwa-3405</link>
      <guid>https://forem.com/angularfirebase/proyecto-fugu-revolucionando-las-aplicaciones-web-progresivas-pwa-3405</guid>
      <description>&lt;p&gt;El &lt;strong&gt;Proyecto Fugu&lt;/strong&gt; busca cerrar la brecha entre las aplicaciones web progresivas (PWA) y las aplicaciones nativas, haciendo que las PWA sean más útiles, atractivas y accesibles para todos. Este esfuerzo es un conjunto de esfuerzos tanto de la comunidad de Chromium como de empresas como Google, Microsoft y otras colaboradoras de la comunidad web en general.&lt;/p&gt;




&lt;h2&gt;
  
  
  ¿Qué son las PWA?
&lt;/h2&gt;

&lt;p&gt;Las &lt;strong&gt;PWA&lt;/strong&gt; son aplicaciones web diseñadas para ser rápidas, confiables y capaces de instalarse en dispositivos como si fueran aplicaciones nativas. Utilizan API modernas para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mejorar la capacidad:&lt;/strong&gt; acceso al hardware y funcionalidades avanzadas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Garantizar la confiabilidad:&lt;/strong&gt; carga rápida y sin interrupciones, incluso sin conexión.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Facilitar la instalación:&lt;/strong&gt; se comportan como apps tradicionales.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Con estas mejoras, las PWA combinan lo mejor de la web y las aplicaciones nativas.&lt;/p&gt;




&lt;h2&gt;
  
  
  ¿Por qué "Proyecto Fugu"?
&lt;/h2&gt;

&lt;p&gt;El nombre "Fugu" hace referencia al pez globo japonés, famoso por ser delicioso, pero peligroso si no se prepara correctamente. Este simbolismo captura la esencia del proyecto: las nuevas API pueden ser muy poderosas, pero si no se implementan con cuidado, pueden generar problemas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ejemplo de capacidades avanzadas y riesgos:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Capacidades avanzadas:&lt;/strong&gt; Acceso al sistema de archivos, herramientas de edición de video, integración con dispositivos Bluetooth y USB.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Riesgos potenciales:&lt;/strong&gt; Estas herramientas deben garantizar la seguridad y privacidad de los usuarios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El proyecto Fugu se enfoca en habilitar estas capacidades mientras se mantiene un equilibrio entre utilidad y seguridad.&lt;/p&gt;




&lt;h2&gt;
  
  
  Principales API del proyecto Fugu
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;File System Access API:&lt;/strong&gt; Permite a las aplicaciones leer y escribir archivos directamente en el sistema del usuario.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Share API y Web Share Target API:&lt;/strong&gt; Facilita compartir contenido entre aplicaciones web y nativas.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contact Picker API:&lt;/strong&gt; Acceso a contactos del dispositivo con permiso explícito.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web Bluetooth y Web USB:&lt;/strong&gt; Conexión con dispositivos físicos para ampliar la funcionalidad.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Badging API:&lt;/strong&gt; Muestra notificaciones y conteos en el ícono de la app instalada.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Beneficios del proyecto Fugu
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compatibilidad universal:&lt;/strong&gt; Las PWA funcionan en cualquier dispositivo con navegador.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Actualizaciones sin complicaciones:&lt;/strong&gt; Siempre al día, sin necesidad de descargas desde una tienda de aplicaciones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mejor experiencia de usuario:&lt;/strong&gt; Acceso a funcionalidades que antes eran exclusivas de aplicaciones nativas.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  La seguridad y el futuro de las PWA
&lt;/h2&gt;

&lt;p&gt;El proyecto Fugu no solo busca expandir las capacidades de las PWA, sino hacerlo de forma segura. Se trabaja para evitar riesgos mediante permisos explícitos y el desarrollo de prácticas responsables para los desarrolladores.&lt;/p&gt;

&lt;p&gt;Con Fugu, las PWA están evolucionando para ser más que una simple versión web. Son una herramienta poderosa que está transformando cómo interactuamos con la tecnología.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus:
&lt;/h2&gt;

&lt;p&gt;La página web del proyecto Momentum &lt;a href="https://momentum-fw.dev/" rel="noopener noreferrer"&gt;https://momentum-fw.dev/&lt;/a&gt; utiliza la API Web USB para instalar un firmware alternativo al por defecto de FlipperZero.&lt;/p&gt;

&lt;p&gt;Más ejemplos e inspiración en:&lt;br&gt;
&lt;a href="https://developer.chrome.com/docs/capabilities/fugu-showcase" rel="noopener noreferrer"&gt;https://developer.chrome.com/docs/capabilities/fugu-showcase&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>spanish</category>
      <category>pwa</category>
      <category>chromium</category>
    </item>
    <item>
      <title>Novedades en Angular 19, ¿Qué hay de nuevo?</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Tue, 19 Nov 2024 15:27:56 +0000</pubDate>
      <link>https://forem.com/angularfirebase/novedades-en-angular-19-que-hay-de-nuevo-1dkg</link>
      <guid>https://forem.com/angularfirebase/novedades-en-angular-19-que-hay-de-nuevo-1dkg</guid>
      <description>&lt;p&gt;Angular sigue evolucionando y la versión 19 no es la excepción. Con un enfoque en la experiencia del desarrollador (Developer Experience), rendimiento mejorado y nuevas herramientas, Angular 19 ofrece características que simplificarán tus proyectos y los harán más eficientes. En este artículo, exploraremos las mejoras en reactividad con &lt;strong&gt;Signals&lt;/strong&gt;, optimización del renderizado y mucho más. Además, este artículo es la onceava iteración desde la versión 8, uno de los primeros artículos en este blog…&lt;/p&gt;

&lt;h2&gt;
  
  
  1.Standalone components como estándar.
&lt;/h2&gt;

&lt;p&gt;Los Standalone Components han sido una adición revolucionaria desde su introducción en Angular 14, y ahora en Angular 19 se convierten en el comportamiento predeterminado. Esto significa que ya no necesitas declarar &lt;code&gt;standalone: true&lt;/code&gt; en cada componente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Antes de Angular19:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;CommonModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;standalone-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./standalone-component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StandaloneComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;CommonModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;standalone-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./standalone-component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StandaloneComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto elimina la necesidad de módulos (NGModules) en la mayoría de los casos, simplificando la estructura de las aplicaciones y fomentando un desarrollo modular. Si aún necesitas trabajar con NgModules, puedes declararlo explícitamente &lt;code&gt;standalone: false&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Hidratación parcial e incremental para un renderizado más rápido
&lt;/h2&gt;

&lt;p&gt;Angular 19 introduce hidratación parcial e incremental, lo que transforma el rendimiento de las aplicaciones renderizadas en el servidor (SSR):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  Hidratación parcial:
&lt;/h3&gt;

&lt;p&gt;Prioriza la carga de componentes críticos, reduciendo el tiempo de interacción inicial.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3&gt;
  
  
  Hidratación incremental:
&lt;/h3&gt;

&lt;p&gt;Difiere la carga de funcionalidades según interacciones del usuario (clics o hovers), optimizando el uso de recursos.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estas técnicas permiten aplicaciones más rápidas e interactivas desde el primer momento, mejorando la experiencia del usuario.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Signals mejorados: Simplificando la reactividad
&lt;/h2&gt;

&lt;p&gt;La integración de &lt;strong&gt;Signals&lt;/strong&gt; en Angular continúa mejorando, ahora con soporte más profundo y nuevas herramientas como &lt;strong&gt;LinkedSignal&lt;/strong&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Qué son los Signals?
&lt;/h3&gt;

&lt;p&gt;Son una API diseñada para manejar estados de forma reactiva y predecible, reduciendo la dependencia de Zone.js. Esto no solo simplifica la depuración, sino que también mejora el rendimiento y reduce el tamaño de los paquetes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ejemplo de uso con Signals:Introducción de linkedSignal:
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;linkedSignal&lt;/code&gt; Es una nueva herramienta que permite crear señales dependientes que se actualizan automáticamente según una señal fuente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;linkedSignal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fuente&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doble&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;linkedSignal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fuente&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;valor&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;doble&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 20&lt;/span&gt;
&lt;span class="nx"&gt;fuente&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;doble&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Mejoras en el API de componentes
&lt;/h2&gt;

&lt;p&gt;Angular 19 introduce &lt;code&gt;ngAfterSignalUpdate&lt;/code&gt; un nuevo hook para reaccionar tras la actualización de un Signal, facilitando la interacción con estados complejos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AfterSignalUpdate&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-lifecycle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Signal&lt;/span&gt; &lt;span class="nx"&gt;Lifecycle&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nf"&gt;button &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;updateSignal()&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Update&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SignalLifecycleComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;AfterSignalUpdate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;mySignal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;updateSignal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mySignal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mySignal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;ngAfterSignalUpdate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Signal updated to:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mySignal&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El nuevo hook &lt;code&gt;ngAfterSignalUpdate&lt;/code&gt; permite a los desarrolladores reaccionar después de que se haya actualizado el signal, lo que puede ser esencial para gestionar cambios en la interfaz de usuario e interacciones de estado complejas.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Tiempos de construcción más rápidos
&lt;/h2&gt;

&lt;p&gt;Gracias a optimizaciones en Angular CLI, las construcciones son más rápidas tanto en entornos de desarrollo como de producción. La incorporación de caché acelera los procesos iterativos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ejemplo: Construcción con caché
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ng&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;optimization&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6.Inyección de dependencias
&lt;/h2&gt;

&lt;p&gt;Ahora Angular infiere automáticamente los tipos en la Inyección de Dependencias (DI), reduciendo el código repetitivo y aumentando la seguridad de tipos.&lt;/p&gt;

&lt;p&gt;Ejemplo: Inferencia de tipos en DI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Antes&lt;/span&gt;
&lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="c1"&gt;// Ahora en Angular 19&lt;/span&gt;
&lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. APIs resource y rxResource: Datos asíncronos simplificados
&lt;/h2&gt;

&lt;p&gt;Manejar datos asíncronos ahora es más fácil con las nuevas &lt;strong&gt;APIs&lt;/strong&gt; experimentales &lt;strong&gt;resource&lt;/strong&gt; y &lt;strong&gt;rxResource&lt;/strong&gt;, diseñadas para Promises y Observables respectivamente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Propiedades de⁣ &lt;code&gt;resource&lt;/code&gt;: ⁣
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Status:&lt;br&gt;
Estado del recurso (cargando, éxito o error).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Value:&lt;br&gt;
Datos recuperados tras la carga.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error:&lt;br&gt;
Gestión de errores.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ejemplo con &lt;code&gt;rxResource&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Estas herramientas unifican la gestión de datos asíncronos, haciendo que los flujos sean más intuitivos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { rxResource } from '@angular/core';

const datos = rxResource(async () =&amp;gt; {
  const respuesta = await fetch('/api/datos');
  return respuesta.json();
});

datos.value.subscribe(data =&amp;gt; console.log(data));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Mejoras al routing
&lt;/h2&gt;

&lt;p&gt;Angular 19 introduce una integración más profunda de Signals con el Router, permitiendo flujos de navegación más reactivos y simplificados. Esto facilita el manejo de parámetros de ruta y de consulta de forma reactiva.&lt;/p&gt;

&lt;p&gt;Ejemplo: Uso de Signals con el Router&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ActivatedRoute&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-route-signal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;h2&amp;gt;Demostración de Rutas&amp;lt;/h2&amp;gt;
    &amp;lt;p&amp;gt;ID de la ruta: {{ signalId() }}&amp;lt;/p&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RouteDemoComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ActivatedRoute&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;signalId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paramMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signalId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bonus&lt;br&gt;
Angular Material incluye nuevas mejoras en los estilos, características de accesibilidad y la interacción de los componentes. Por ejemplo, componentes como &lt;code&gt;mat-menu&lt;/code&gt; y &lt;code&gt;mat-select&lt;/code&gt; ahora son más intuitivos y fáciles de usar.&lt;br&gt;
Ejemplo: Uso mejorado de &lt;code&gt;mat-menu&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;mat-button&lt;/span&gt; &lt;span class="na"&gt;[matMenuTriggerFor]=&lt;/span&gt;&lt;span class="s"&gt;"menu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Menu&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;mat-menu&lt;/span&gt; &lt;span class="na"&gt;#menu&lt;/span&gt;&lt;span class="err"&gt;="&lt;/span&gt;&lt;span class="na"&gt;matMenu&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;mat-menu-item&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 1&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;mat-menu-item&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 2&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;mat-menu-item&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Item 3&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/mat-menu&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusión.
&lt;/h2&gt;

&lt;p&gt;Angular 19 es un paso significativo en la evolución del framework. Desde el uso predeterminado de Standalone Components, pasando por las mejoras en reactividad con Signals, hasta la optimización en SSR, esta versión ofrece herramientas para construir aplicaciones más rápidas, reactivas y mantenibles.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Te animas para actualizar?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Guía para actualizar en :&lt;a href="https://angular.dev/update-guide/?v=18.0-19.0&amp;amp;l=1" rel="noopener noreferrer"&gt;https://angular.dev/update-guide/?v=18.0-19.0&amp;amp;l=1&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/core @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Comparte tu experiencia&lt;/strong&gt; con estas nuevas funcionalidades y sigue explorando el futuro del desarrollo con Angular. 🚀&lt;/p&gt;

&lt;p&gt;¡Gracias a &lt;a class="mentioned-user" href="https://dev.to/damiansire"&gt;@damiansire&lt;/a&gt; por dar el visto bueno a este post!&lt;/p&gt;

</description>
      <category>spanish</category>
      <category>angular</category>
      <category>angular19</category>
      <category>webdev</category>
    </item>
    <item>
      <title>El futuro de Angular es</title>
      <dc:creator>Antonio Cardenas </dc:creator>
      <pubDate>Thu, 12 Sep 2024 05:28:24 +0000</pubDate>
      <link>https://forem.com/angularfirebase/el-futuro-de-angular-es-1if1</link>
      <guid>https://forem.com/angularfirebase/el-futuro-de-angular-es-1if1</guid>
      <description>&lt;h2&gt;
  
  
  Componentes independientes
&lt;/h2&gt;

&lt;p&gt;Angular v19 hará que &lt;code&gt;standalone: true&lt;/code&gt; sea el valor predeterminado para componentes, directivas y pipes.&lt;/p&gt;

&lt;p&gt;En la V14 se introdujo una vista previa para desarrolladores de la &lt;a href="https://angular.dev/guide/components/importing#standalone-components" rel="noopener noreferrer"&gt;función "standalone"&lt;/a&gt;, que hizo posible por primera vez construir una aplicación que no dependiera de NgModules. Desde entonces, &lt;strong&gt;Standalone&lt;/strong&gt; se ha estabilizado y se ha convertido en la forma recomendada por el equipo de Angular para escribir código Angular. El CLI genera componentes &lt;code&gt;standalone: true&lt;/code&gt; de manera predeterminada, y la documentación de Angular enseña primero standalone a todos los nuevos desarrolladores de Angular. La adopción es fuerte y sigue creciendo en todo el ecosistema Angular, tanto en las aplicaciones más grandes escritas en Angular dentro de Google como en aplicaciones en toda la Internet.&lt;/p&gt;

&lt;p&gt;Standalone no solo facilita la curva de aprendizaje y el uso del framework de Angular, sino que también ha habilitado algunas características nuevas emocionantes. En &lt;code&gt;@angular/router&lt;/code&gt;, &lt;code&gt;loadComponent&lt;/code&gt; simplifica significativamente la carga diferida de rutas a nivel de componente y se basa en la funcionalidad standalone. La &lt;a href="https://angular.dev/guide/directives/directive-composition-api" rel="noopener noreferrer"&gt;API de Composición de Directivas&lt;/a&gt; permite un mejor modelo de composición para el comportamiento de los componentes, permitiendo que las directivas standalone se apliquen en la declaración de un componente o directiva anfitrión. Y, por supuesto, &lt;a href="https://angular.dev/guide/defer" rel="noopener noreferrer"&gt;Deferrable Views&lt;/a&gt; carga de forma diferida y transparente los componentes y directivas standalone a nivel de plantilla, facilitando más que nunca la optimización de tus aplicaciones Angular.&lt;/p&gt;

&lt;p&gt;En v19 daremos el siguiente paso, y cambiaremos el valor predeterminado de la opción &lt;code&gt;standalone&lt;/code&gt; en componentes, directivas y pipes, para que nunca más tengas que escribir "standalone: true". Con este cambio, los componentes como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserAvatarComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AccountListComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormsModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user-profile-component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserProfileComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Ejemplo que muestra la opción standalone en Angular hoy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ahora se escribirán de esta manera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserAvatarComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AccountListComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormsModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user-profile-component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserProfileComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Ejemplo que muestra la opción standalone eliminada en v19&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ¿Qué pasa si sigo usando NgModules?
&lt;/h2&gt;

&lt;p&gt;Eso está bien: no se está descontinuando la opción standalone ni los propios NgModules. Todavía podrás escribir componentes NgModule, especificando &lt;code&gt;standalone: false&lt;/code&gt; en el decorador del componente.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué va a pasar con mi código existente, ya sea con Standalone o NgModules?
&lt;/h2&gt;

&lt;p&gt;Como parte del ng update para v19, se aplicará una migración automatizada que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Se eliminará la etiqueta &lt;code&gt;standalone: true&lt;/code&gt; a los componentes standalone existentes, ya que será el nuevo valor predeterminado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se agregará &lt;code&gt;standalone: false&lt;/code&gt; a los componentes ngModule existentes para que sigan funcionando.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Opcionalmente, podrás configurar la opción de compilador &lt;code&gt;strictStandalone&lt;/code&gt; para exigir que solo se escriban componentes standalone en tu aplicación.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Qué pasa con FormsModule y otras bibliotecas npm con NgModules?
&lt;/h2&gt;

&lt;p&gt;Aquí no cambiará nada. Los componentes standalone pueden seguir importando dependencias de NgModule según sea necesario, incluso con la opción de compilador strictStandalone habilitada.&lt;/p&gt;

&lt;p&gt;Si estás creando una biblioteca publicada en NPM, tampoco necesitas hacer nada: tus componentes se comportarán correctamente cuando los usuarios los importen, independientemente de si están usando la V19 con el nuevo valor predeterminado o no.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: 
&lt;/h2&gt;

&lt;p&gt;En la versión 19 se introduce la capacidad de detectar si un componente o directiva importada en un componente está realmente siendo utilizado, información que será mostrada en nuestro CLI como una advertencia acerca de los imports que no estamos usando, pero que están siendo llamados.&lt;/p&gt;

&lt;p&gt;Si no deseas ver estos warnings, puedes añadir este código a: &lt;code&gt;tsconfig.json&lt;/code&gt;&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;angularCompilerOptions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;extendedDiagnostics&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;checks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unusedStandaloneImports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;suppress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Quizás en esta versión o en las siguientes podamos ver la implementación de AI, como ser Gemini UI generativa como V0 o alguna otra herramienta útil de parte del equipo de Angular, el cual arduamente trabaja para mejorar nuestra experiencia como desarrolladores.&lt;/p&gt;

&lt;p&gt;Articulo original &lt;a href="https://blog.angular.dev/the-future-is-standalone-475d7edbc706" rel="noopener noreferrer"&gt;aquí&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>spanish</category>
      <category>development</category>
    </item>
  </channel>
</rss>
