Tecnología
Cómo recoger en el padre un dato emitido por un componente Angular
Un evento bien tipado conecta al hijo con el padre sin crear dependencias innecesarias entre componentes.

Diseñado por Freepik
Un componente hijo puede comunicar al padre un texto, una selección o cualquier otro dato mediante un evento propio. El hijo lo emite cuando ocurre algo relevante y el padre lo recibe con $event, normalmente para guardarlo en una propiedad, actualizar una señal o iniciar una acción. La comunicación se declara en el hijo y se escucha en la plantilla del padre; no hace falta acceder directamente a las variables internas del componente que lo contiene.
Angular ofrece dos formas habituales de declarar esa salida: el patrón tradicional con @Output() y EventEmitter, y la API más reciente basada en output(). En ambos casos, el enlace del padre tiene la misma forma: (nombreDelEvento)="manejador($event)". La diferencia está en cómo se define el emisor y en las herramientas que acompañan a cada alternativa, no en el recorrido básico del dato.
El dato viaja como un evento, no como una variable compartida
La idea puede parecerse a pasar un valor de una clase a otra, pero Angular plantea una relación más explícita: el hijo anuncia que ha sucedido algo y adjunta la información necesaria. Por ejemplo, una lista puede emitir el elemento seleccionado, un formulario puede comunicar el texto introducido y un diálogo puede informar de que se ha confirmado. El evento es el canal público que el componente ofrece al exterior, mientras que sus propiedades privadas siguen perteneciendo al propio hijo.
En el padre, la plantilla escucha ese canal como escucharía un clic u otro evento asociado a un elemento. Si el hijo expone una salida llamada seleccionarItem, el padre puede escribir (seleccionarItem)="onSeleccion($event)". Cuando el hijo emita el dato, Angular invocará el manejador y colocará el valor emitido en $event. El padre decide entonces qué hacer con él y en qué parte de su estado conservarlo.
Esta relación es directa: el output no se propaga automáticamente por todos los niveles del árbol de componentes. Si un componente nieto emite un evento, no basta con que un abuelo intente escucharlo como si los eventos del navegador subieran por el DOM. El componente que contiene al hijo es quien recibe la salida enlazada en su plantilla; para alcanzar otros niveles hay que reenviar el evento de forma explícita o elegir otra arquitectura.
La forma clásica con @Output y EventEmitter
En proyectos que ya usan decoradores, la fórmula conocida sigue siendo clara y válida. El hijo importa Output y EventEmitter desde Angular, declara una propiedad con el tipo del dato que emitirá y llama a emit() cuando se produce el hecho relevante. Una declaración como @Output() seleccion = new EventEmitter<Producto>(); indica que el evento transportará un valor de tipo Producto.
El método que causa la emisión puede ser breve: elegir(producto: Producto): void { this.seleccion.emit(producto); }. Desde el componente padre, la plantilla escucha esa propiedad con <app-lista (seleccion)="guardarSeleccion($event)"></app-lista>. El manejador podría asignar el argumento a una propiedad, por ejemplo guardarSeleccion(producto: Producto): void { this.productoActual = producto; }. Así, el tipo declarado en el hijo se conserva en la comunicación y ayuda a detectar incompatibilidades.
No es obligatorio escribir un método intermedio si la acción es sencilla. El padre también puede asignar el valor directamente en la plantilla, como en (seleccion)="productoActual = $event". Sin embargo, un manejador con nombre suele resultar más legible cuando hay que validar el dato, actualizar varias propiedades o coordinar una acción. La plantilla expresa quién escucha; el código del padre concentra la respuesta, sin trasladar al hijo decisiones que pertenecen al contenedor.
Qué representa $event y cómo se conserva el tipo
$event es el valor entregado por la emisión actual. Si el hijo ejecuta this.seleccion.emit(producto), el padre recibe ese objeto; si emite una cadena, recibe una cadena. El dato no tiene que ser siempre texto ni un valor simple: puede ser un número, un booleano, un objeto propio del programa o una estructura con varios campos. El parámetro genérico de EventEmitter documenta el tipo esperado y mejora la comprobación y la ayuda del editor.
También se puede escuchar el evento sin pasar $event al manejador cuando solo interesa saber que ocurrió. La plantilla puede usar (guardado)="actualizarVista()", aunque el output lleve información. Esta opción tiene sentido si la respuesta no depende del contenido emitido; si el padre necesita el identificador, el resultado o el elemento seleccionado, debe recibirlo de forma explícita. Dejar fuera el dato que determina la acción suele obligar a buscarlo por otro camino y complica el diseño.
Los nombres distinguen mayúsculas de minúsculas, por lo que la etiqueta del padre debe coincidir con la salida que publica el hijo. Si la propiedad se llama seleccion, escuchar (Seleccion) no equivale a escuchar (seleccion). También es posible asignar un alias a un output para que el nombre público difiera del nombre de la propiedad, pero esa capa adicional conviene reservarla para casos donde aporte claridad o compatibilidad. Un nombre estable y descriptivo hace visible el contrato del componente sin obligar a abrir su implementación.
La API output() y su relación con las señales
Angular incorporó output() como una alternativa moderna para declarar eventos de componente. El hijo puede exponer, por ejemplo, readonly buscar = output<string>(); y emitir el contenido con this.buscar.emit(texto). En el padre, la escucha se escribe igual que con el patrón clásico: (buscar)="filtrar($event)". Quien lee la plantilla no necesita aprender una sintaxis de enlace nueva para cambiar de API.
Aunque esta API encaja con las herramientas actuales de Angular, output() no es en sí misma una señal. Devuelve una referencia de salida con la que el componente puede emitir valores; no se lee como una señal ni se actualiza mediante .set(). La semejanza con las API de señales no convierte al output en estado reactivo: su función sigue siendo notificar eventos hacia fuera, mientras que las señales representan valores que el componente mantiene y consulta.
La alternativa tampoco obliga a reemplazar de una vez todos los outputs clásicos. En una base de código consolidada, ambos estilos pueden convivir mientras el equipo migra por componentes o mantiene el patrón que ya usa el proyecto. La documentación de Angular presenta la nueva API como una opción estable en las versiones recientes, pero la elección concreta depende de la versión instalada y de las convenciones del repositorio. En particular, una migración automática puede actualizar declaraciones e imports, aunque el código que usa un emisor de formas especiales quizá necesite revisión.
Cuándo encaja model() y cuándo basta un evento
Hay componentes que reciben un valor y también comunican sus cambios. Un control de puntuación, por ejemplo, puede mostrar un número que administra el padre y avisar cuando el usuario lo modifica. En ese caso, Angular dispone de model(), una API orientada a propiedades enlazables en dos direcciones. El componente hijo declara el modelo y el padre puede vincularlo con una sintaxis de doble enlace, en vez de escribir manualmente toda la pareja de entrada y evento de cambio.
Ese comportamiento es diferente de emitir cualquier acontecimiento del componente. Un aviso de guardado, una selección puntual o un cierre de diálogo suelen ser eventos, no valores que deban sincronizarse continuamente. model() resulta apropiado cuando el hijo edita un dato que pertenece al estado controlado por el padre; para notificar que ocurrió una acción, un output normal mantiene mejor la intención. Si se prefiere un flujo explícito, el padre también puede escuchar el evento de cambio y actualizar su estado sin usar el enlace bidireccional.
La distinción evita convertir cada comunicación en una sincronización de doble sentido. Si un hijo solo informa de que el usuario pulsó confirmar, no hace falta representar esa acción como una propiedad que cambie de valor en ambos componentes. En cambio, cuando el componente funciona como un control editable y el valor actual debe reflejarse en ambos lados, el modelo puede reducir código repetido. La forma de comunicación debe describir el vínculo real entre el dato y el componente, no solo ahorrar unas líneas en la plantilla.
Ejemplos cotidianos: una selección, un diálogo o una búsqueda
En una lista de resultados, el hijo puede emitir el elemento elegido y el padre guardar ese producto para mostrar su detalle. El payload puede ser el objeto completo si el contenedor necesita varios de sus campos, o un identificador si solo requiere localizarlo en otra estructura. No hay una regla universal que obligue a emitir siempre uno u otro. Conviene enviar la información mínima que permita al padre reaccionar, sin convertir el evento en una copia innecesaria de grandes estructuras de estado.
Un diálogo puede publicar una salida cuando se confirma y otra cuando se cancela, o emitir un único evento con un resultado que distinga ambas situaciones. El padre decide entonces si añade el elemento, descarta los cambios o cierra la vista. Lo importante es que el hijo describa lo que ha ocurrido en su interfaz, no que invoque directamente una operación interna del padre. Esa separación permite reutilizar el diálogo en otra pantalla sin que conozca el destino de cada resultado.
En una caja de búsqueda, el hijo puede emitir el texto introducido y el padre usarlo como filtro o como término de consulta. Si se comunica cada pulsación, el evento puede repetirse con mucha frecuencia; por eso, según el comportamiento buscado, la lógica puede esperar a que el usuario deje de escribir o descartar valores repetidos. Esas decisiones pertenecen al flujo que procesa la búsqueda. El output transporta el cambio; no determina por sí solo cuándo ni cómo se consulta la información.
También es habitual emitir un resultado con varios datos, como un estado de éxito y un identificador generado. Una estructura tipada deja clara esa forma, por ejemplo { ok: boolean; id?: string }. El padre puede mostrar una confirmación, actualizar una lista o cambiar de pantalla según corresponda. Si el evento solo comunica que algo se completó y el detalle no interesa al contenedor, puede ser suficiente una salida sin payload. La cantidad de información debe responder a la necesidad real del consumidor.
Eventos, órdenes y límites entre componentes
Un output bien diseñado informa de un hecho que tuvo lugar: se seleccionó un elemento, se guardó un formulario o se cerró una ventana. No debería convertir al hijo en un mando a distancia que ordena a un componente ajeno ejecutar una operación específica. El hijo comunica lo que ha sucedido y el padre decide cómo responder. Esta diferencia es pequeña en apariencia, pero reduce dependencias y facilita probar o reutilizar cada pieza.
Por ejemplo, un nombre como elementoSeleccionado describe un resultado observable. En cambio, una salida llamada actualizarContadorDelPadre revela que el hijo conoce una decisión que debería tomar quien lo contiene. El primero permite que un consumidor actualice un contador, navegue a otra vista o no haga nada; el segundo ata el componente a una tarea particular. Los nombres que expresan hechos ayudan a mantener el contrato independiente de la lógica de negocio.
La misma cautela se aplica a la cantidad de datos emitidos y a su frecuencia. Enviar objetos completos puede acoplar al consumidor a detalles que no necesita; emitir con cada cambio intermedio puede producir trabajo adicional si la respuesta implica cálculos o consultas. Normalizar el texto, evitar emisiones duplicadas o agrupar la reacción son decisiones posibles según el caso, pero no hay una optimización única que deba aplicarse siempre. El diseño debe equilibrar claridad, coste y necesidades concretas de la interfaz.
Outputs y RxJS: conectar un evento con un flujo
Cuando el componente ya trabaja con observables, Angular permite interconectar esos flujos con los outputs mediante utilidades de @angular/core/rxjs-interop. outputFromObservable() permite exponer como salida los valores que emite un observable; así se evita escribir una suscripción manual solo para volver a emitir cada elemento. La plantilla del padre conserva el enlace de evento habitual, con la misma claridad que si el hijo usara directamente output().
En el sentido inverso, outputToObservable() permite tratar una referencia de salida como observable y componerla con operadores de RxJS en el código del padre. Puede ser útil si la reacción necesita filtrado, combinación con otros flujos o una transformación antes de actualizar el estado. La interoperabilidad mantiene el evento como contrato del componente, mientras lleva al flujo reactivo el procesamiento que ya se expresa mejor con observables.
No conviene añadir RxJS por sistema a una comunicación simple. Si el padre solo debe guardar un valor cuando llega, llamar a un manejador suele ser más fácil de leer y probar. Los operadores cobran sentido cuando resuelven una necesidad real de composición temporal o transformación. Además, si se trasladan manejadores complejos a flujos, hay que mantener esa lógica en un lugar donde el equipo pueda seguirla y verificarla; un template abarrotado de expresiones pierde rápidamente su ventaja de brevedad.
Errores habituales al escuchar el valor del hijo
El fallo más directo es que el hijo emita un nombre y el padre escuche otro, algo que también puede deberse a diferencias de mayúsculas. Otra confusión frecuente es llamar al método de emisión sin incluir el dato esperado o declarar un tipo demasiado amplio para que el compilador pueda detectar errores. Revisar juntos el nombre de la salida, su tipo y el argumento de emit() suele revelar enseguida dónde se rompe la comunicación. El contrato debe coincidir en los dos lados del enlace.
También puede parecer que el evento no llega porque se intenta escucharlo desde un antepasado que no contiene directamente al componente que lo emite. Los outputs de Angular no hacen bubbling por el árbol del DOM como los eventos nativos del navegador. Si el padre inmediato escucha la salida, puede volver a emitirla con su propio nombre; si varios componentes necesitan compartir estado o comunicarse sin relación directa, repetir ese reenvío nivel por nivel puede ser una señal de que hace falta otra solución.
Por último, un output no sustituye a un servicio compartido cuando la información debe circular entre componentes independientes o atravesar partes distintas de la aplicación. Tampoco es necesario crear un servicio para un valor local que solo conecta a un hijo con su contenedor: añadir una capa puede oscurecer un vínculo que ya es evidente en la plantilla. La regla práctica es mantener la comunicación cerca de quienes la necesitan y cambiar de mecanismo cuando el alcance deja de ser local.
Una comunicación explícita que deja el estado en su sitio
Recibir un valor de un hijo se reduce a un acuerdo visible: el componente declara qué evento puede emitir, indica qué dato transporta y lo envía cuando sucede algo significativo; el padre escucha ese nombre y decide cómo incorporar el payload. Con @Output() y EventEmitter o con output(), la plantilla del contenedor recibe $event y mantiene el control sobre su propio estado. La claridad del flujo importa más que escoger la API por novedad.
Ese acuerdo también ayuda a entender el código sin recorrer toda la aplicación. Un nombre preciso y un tipo concreto muestran qué ofrece el hijo, mientras el manejador revela qué consecuencia tiene en el padre. Cuando la relación es editable en dos direcciones, model() puede expresar mejor el vínculo; cuando hay flujos existentes, RxJS permite componerlos; cuando se trata de un evento puntual, el enlace directo suele bastar.
La frontera importante no está entre lo clásico y lo moderno, sino entre una comunicación local, explícita y fácil de seguir y una cadena de dependencias que obliga a componentes a conocer decisiones ajenas. Si el dato afecta solo al contenedor inmediato, un output mantiene el diseño sencillo. Si debe alcanzar componentes sin relación directa, conviene replantear dónde vive el estado. Así, cada componente informa de lo que le ocurre y el nivel adecuado decide qué significa.

Actualidad¿Qué se sabe hoy de los terremotos de Venezuela y cómo sigue el país?
Salud¿Por qué me duelen las piernas por dentro? Causas, síntomas y alertas
Naturaleza¿Dónde siguen activos los incendios en España este 28 de septiembre?
Economía¿Cómo funciona la nueva cuenta de Revolut al 3,51% TAE en España?
Actualidad¿Qué pasó con el terremoto de Colombia? Balance, víctimas y réplicas
ActualidadSan Miguel 2026: fecha, día de la semana y santoral
Actualidad¿Cuánto cuesta el desfile de la Fiesta Nacional en Madrid en 2026?
Economía¿Cuándo llega Kaufland a España y qué ciudades tendrán compra online?
Ocio¿Cuándo es Halloween 2026 en España y qué día se celebra este año?
ActualidadCalendario laboral 2026: ¿cuántos días festivos tendrás en España?
Salud¿Por qué mi sudor huele mal y antes no? Causas y cuándo preocuparse
Ocio¿Cómo queda la Liga Endesa? Fichajes, bajas y renovaciones 2026-27









