¿No hay un equivalente a $scope.emit()
, o $scope.broadcast()
en angular?
Conozco la EventEmitter
funcionalidad, pero por lo que entiendo, solo emitirá un evento para el elemento HTML principal.
¿Qué pasa si necesito comunicarme entre FX? hermanos o entre un componente en la raíz del DOM y un elemento anidado en varios niveles de profundidad?
Respuestas:
No hay un equivalente a
$scope.emit()
, o$scope.broadcast()
desde AngularJS. EventEmitter dentro de un componente se acerca, pero como mencionó, solo emitirá un evento al componente primario inmediato.En Angular, hay otras alternativas que intentaré explicar a continuación.
Los enlaces @Input () permiten que el modelo de aplicación se conecte en un gráfico de objeto dirigido (raíz a hojas). El comportamiento predeterminado de la estrategia del detector de cambios de un componente es propagar todos los cambios a un modelo de aplicación para todos los enlaces desde cualquier componente conectado.
Aparte: hay dos tipos de modelos: Ver modelos y Modelos de aplicación. Un modelo de aplicación está conectado a través de enlaces @Input (). Un modelo de vista es solo una propiedad de componente (no decorada con @Input ()) que está vinculada en la plantilla del componente.
Para responder tu pregunta:
¿Qué sucede si necesito comunicarme entre componentes hermanos?
Modelo de aplicación compartida : los hermanos pueden comunicarse a través de un modelo de aplicación compartida (al igual que angular 1). Por ejemplo, cuando un hermano hace un cambio en un modelo, el otro hermano que tiene enlaces al mismo modelo se actualiza automáticamente.
Eventos de componentes : los componentes secundarios pueden emitir un evento al componente principal mediante enlaces @Output (). El componente principal puede manejar el evento y manipular el modelo de aplicación o su propio modelo de vista. Los cambios en el modelo de aplicación se propagan automáticamente a todos los componentes que se unen directa o indirectamente al mismo modelo.
Eventos de servicio : los componentes pueden suscribirse a eventos de servicio. Por ejemplo, dos componentes hermanos pueden suscribirse al mismo evento de servicio y responder modificando sus respectivos modelos. Más sobre esto a continuación.
¿Cómo puedo comunicarme entre un componente raíz y un componente anidado a varios niveles de profundidad?
$scope.broadcast()
Angular 1. La siguiente sección describe esta idea con más detalle.Ejemplo de un servicio observable que usa eventos de servicio para propagar cambios
Aquí hay un ejemplo de un servicio observable que usa eventos de servicio para propagar cambios. Cuando se agrega TodoItem, el servicio emite un evento que notifica a sus suscriptores componentes.
Así es como un componente raíz se suscribiría al evento:
Un componente hijo anidado en varios niveles profundos se suscribiría al evento de la misma manera:
Aquí está el componente que llama al servicio para activar el evento (puede residir en cualquier parte del árbol de componentes):
Referencia: Detección de cambios en angular
fuente
itemAdded$
. ¿Es una convención RxJS o algo así? ¿De donde viene esto?street
propiedad del modelo de la aplicación, pero dado que Angular 2 implementa la detección de cambios por identidad / referencia, no se propagan cambios (onChanges
no se llama), porque la referencia del modelo de la aplicación no ha cambiado ( cont ...)El siguiente código como ejemplo de un reemplazo para $ scope.emit () o $ scope.broadcast () en Angular 2 usando un servicio compartido para manejar eventos.
Ejemplo de uso:
Transmitir:
Oyente:
Puede soportar múltiples argumentos:
fuente
off(name, listener) { this.listeners[name] = this.listeners[name].filter(x => x != listener); }
Estoy usando un servicio de mensajes que envuelve un rxjs
Subject
(TypeScript)Ejemplo de Plunker: servicio de mensajes
Los componentes pueden suscribirse y transmitir eventos (remitente):
(receptor)
El
subscribe
método deMessageService
devuelve unSubscription
objeto rxjs , que se puede cancelar de la siguiente manera:También vea esta respuesta: https://stackoverflow.com/a/36782616/1861779
Ejemplo de Plunker: servicio de mensajes
fuente
Property 'filter' does not exist on type 'Subject<EventMessage>'.
this.handler.pipe(filter(...))
. Ver operadores alquilables .return this.handler.pipe( filter(message => message.type === type), map(message => message.payload) ).subscribe(callback);
NO use EventEmitter para la comunicación de su servicio.
Debe usar uno de los tipos Observables. Personalmente me gusta BehaviorSubject.
Ejemplo simple:
Puedes pasar el estado inicial, aquí paso nulo
Cuando quieres actualizar el tema
Observe desde cualquier servicio o componente y actúe cuando reciba nuevas actualizaciones.
Aquí hay más información. .
fuente
Puede usar
EventEmitter oobservables para crear un servicio de Eventbus que registre con DI. Cada componente que quiere participar solo solicita el servicio como parámetro constructor y emite y / o se suscribe a eventos.Ver también
fuente
Mi forma favorita de hacerlo es usar el sujeto de comportamiento o el emisor de eventos (casi el mismo) en mi servicio para controlar todo mi subcomponente.
Usando cli angular, ejecute ng gs para crear un nuevo servicio y luego use un BehaviorSubject o EventEmitter
Cuando lo haga, todos los componentes que utilicen su servicio como proveedor serán conscientes del cambio. Simplemente suscríbase al resultado como lo hace con eventEmitter;)
fuente
He creado una muestra de pub-sub aquí:
http://www.syntaxsuccess.com/viewarticle/pub-sub-in-angular-2.0
La idea es utilizar los sujetos RxJs para conectar un observador y observables como una solución genérica para emitir y suscribirse a eventos personalizados. En mi muestra utilizo un objeto de cliente con fines de demostración
Aquí también hay una demostración en vivo: http://www.syntaxsuccess.com/angular-2-samples/#/demo/pub-sub
fuente
Esta es mi versión
utilizar:
}
emitir:
fuente
Implementamos una directiva observable ngModelChange que envía todos los cambios del modelo a través de un emisor de eventos que usted instancia en su propio componente. Simplemente tiene que vincular su emisor de eventos a la directiva.
Ver: https://github.com/atomicbits/angular2-modelchangeobservable
En html, vincule su emisor de eventos (countryChanged en este ejemplo):
En su componente de mecanografiado, realice algunas operaciones asíncronas en EventEmitter:
fuente
Eventos de servicio: los componentes pueden suscribirse a eventos de servicio. Por ejemplo, dos componentes hermanos pueden suscribirse al mismo evento de servicio y responder modificando sus respectivos modelos. Más sobre esto a continuación.
Pero asegúrese de darse de baja para destruir el componente principal.
fuente