Tengo un ListComponent. Cuando se hace clic en un elemento en ListComponent, los detalles de ese elemento deben mostrarse en DetailComponent. Ambos están en la pantalla al mismo tiempo, por lo que no hay enrutamiento involucrado.
¿Cómo le digo a DetailComponent en qué elemento de ListComponent se hizo clic?
He considerado emitir un evento hasta el elemento principal (AppComponent) y hacer que el elemento principal establezca selectedItem.id en DetailComponent con un @Input. O podría usar un servicio compartido con suscripciones observables.
EDITAR: Sin embargo, configurar el elemento seleccionado a través de event + @Input no activa DetailComponent, en caso de que necesite ejecutar código adicional. Así que no estoy seguro de que sea una solución aceptable.
Pero ambos métodos parecen mucho más complejos que la forma de hacer las cosas de Angular 1, que era a través de $ rootScope. $ Broadcast o $ scope. $ Parent. $ Broadcast.
Como todo en Angular 2 es un componente, me sorprende que no haya más información sobre la comunicación de componentes.
¿Hay otra forma más sencilla de lograr esto?
fuente
Respuestas:
Actualizado a rc.4: al intentar que los datos pasen entre componentes hermanos en angular 2, la forma más sencilla en este momento (angular.rc.4) es aprovechar la inyección de dependencia jerárquica de angular2 y crear un servicio compartido.
Aquí estaría el servicio:
Ahora, aquí estaría el componente PARENT
y sus dos hijos
niño 1
niño 2 (es hermano)
AHORA: Cosas a tener en cuenta al usar este método.
fuente
directives
ya no se declaran en el componente.En el caso de 2 componentes diferentes (componentes no anidados, padre / hijo / nieto) le sugiero esto:
fuente
Una forma de hacerlo es utilizar un servicio compartido .
Sin embargo, encuentro que la siguiente solución es mucho más simple, permite compartir datos entre 2 hermanos (probé esto solo en Angular 5 )
En su plantilla de componente principal:
app-sibling2.component.ts
fuente
Hay una discusión al respecto aquí.
https://github.com/angular/angular.io/issues/2663
La respuesta de Alex J es buena pero ya no funciona con Angular 4 actual a partir de julio de 2017.
Y este vínculo más profundo demostraría cómo comunicarse entre hermanos utilizando un servicio compartido y observable.
https://embed.plnkr.co/P8xCEwSKgcOg07pwDrlO/
fuente
Una directiva puede tener sentido en determinadas situaciones para "conectar" componentes. De hecho, las cosas que se conectan ni siquiera necesitan ser componentes completos y, a veces, es más liviano y en realidad más simple si no lo son.
Por ejemplo, tengo un
Youtube Player
componente (envoltura de la API de Youtube) y quería algunos botones de control para él. La única razón por la que los botones no son parte de mi componente principal es que están ubicados en otra parte del DOM.En este caso, en realidad es solo un componente de 'extensión' que solo será útil con el componente 'principal'. Digo 'padre', pero en DOM es un hermano, así que llámalo como quieras.
Como dije, ni siquiera necesita ser un componente completo, en mi caso es solo un
<button>
(pero podría ser un componente).En el HTML para
ProductPage.component
, ¿dóndeyoutube-player
está obviamente mi componente que envuelve la API de Youtube?La directiva conecta todo por mí, y no tengo que declarar el evento (click) en el HTML.
Por lo tanto, la directiva puede conectarse muy bien al reproductor de video sin tener que participar
ProductPage
como mediador.Esta es la primera vez que hago esto, por lo que aún no estoy seguro de cuán escalable podría ser para situaciones mucho más complejas. Por esto aunque estoy contento y deja mi HTML simple y las responsabilidades de todo distinto.
fuente
player
. Si dejo fuera la primera mención del jugador, obtengo un rangeError. Estoy perplejo en cuanto a cómo se supone que funciona esto._player
para el campo privado que representa al jugador, así que sí, obtendría un error si copiara esto exactamente. Actualizará. ¡Lo siento!Aquí hay una explicación práctica simple: Simplemente explicado aquí
En call.service.ts
Componente desde donde desea llamar a observable para informar a otro componente que se hace clic en el botón
Componente en el que desea realizar una acción en el botón que hizo clic en otro componente
Mi comprensión clara sobre la comunicación de componentes al leer esto: http://musttoknow.com/angular-4-angular-5-communicate-two-components-using-observable-subject/
fuente
El servicio compartido es una buena solución para este problema. Si también desea almacenar información sobre la actividad, puede agregar el servicio compartido a la lista de proveedores de sus módulos principales (módulo de aplicación).
Entonces puede proporcionarlo directamente a sus componentes,
Con el Servicio Compartido puede usar funciones o puede crear un Asunto para actualizar varios lugares a la vez.
En su componente de lista, puede publicar la información del elemento en el que se hizo clic,
y luego puede obtener esta información en su componente de detalle:
Obviamente, los datos que enumeran los componentes compartidos pueden ser cualquier cosa. Espero que esto ayude.
fuente
Debe configurar la relación padre-hijo entre sus componentes. El problema es que puede simplemente inyectar los componentes secundarios en el constructor del componente principal y almacenarlo en una variable local. En su lugar, debe declarar los componentes secundarios en su componente principal mediante el
@ViewChild
declarador de propiedades. Así es como debería verse su componente principal:https://angular.io/docs/ts/latest/api/core/index/ViewChild-var.html
https://angular.io/docs/ts/latest/cookbook/component-communication.html#parent-to-view-child
Tenga cuidado, el componente hijo no estará disponible en el constructor del componente padre, justo después de
ngAfterViewInit
llamar al gancho del ciclo de vida. Para atrapar este gancho, simplemente implemente laAfterViewInit
interfaz en su clase principal de la misma manera que lo haría conOnInit
.Pero, hay otros declaradores de propiedades como se explica en esta nota de blog: http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/
fuente
Sujetos de conducta.Escribí un blog sobre eso.
En este ejemplo, estoy declarando un sujeto de comportamiento noid de tipo número. También es un observable. Y si "sucedió algo", esto cambiará con la función new () {}.
Entonces, en los componentes del hermano, uno llamará a la función, para hacer el cambio, y el otro se verá afectado por ese cambio, o viceversa.
Por ejemplo, obtengo la identificación de la URL y actualizo el noid del asunto del comportamiento.
Y desde el otro lado, puedo preguntar si ese ID es "lo que quiera" y hacer una elección después de eso, en mi caso, si quiero eliminar una tarea, y esa tarea es la URL actual, tiene que redirigirme. a la casa:
fuente
Esto no es exactamente lo que quieres, pero seguro que te ayudará.
Me sorprende que no haya más información sobre la comunicación de componentes <=> considere este tutorial de angualr2
Para la comunicación de componentes hermanos, sugeriría ir con
sharedService
. Sin embargo, también hay otras opciones disponibles.Consulte el enlace en la parte superior para obtener más código.
Editar: esta es una demostración muy pequeña. Ya has mencionado que ya lo has probado
sharedService
. Así que considere este tutorial de angualr2 para obtener más información.fuente
He estado transmitiendo métodos de establecimiento del padre a uno de sus hijos a través de un enlace, llamando a ese método con los datos del componente hijo, lo que significa que el componente padre se actualiza y luego puede actualizar su segundo componente hijo con los nuevos datos. Sin embargo, requiere vincular 'esto' o usar una función de flecha.
Esto tiene la ventaja de que los niños no están tan acoplados entre sí, ya que no necesitan un servicio compartido específico.
No estoy del todo seguro de que esta sea la mejor práctica, sería interesante escuchar las opiniones de otros al respecto.
fuente