Eu tenho um ListComponent. Quando um item é clicado em ListComponent, os detalhes desse item devem ser mostrados em DetailComponent. Ambos estão na tela ao mesmo tempo, então não há roteamento envolvido.
Como posso informar a DetailComponent qual item em ListComponent foi clicado?
Considerei emitir um evento para o pai (AppComponent) e fazer com que o pai definisse selectedItem.id em DetailComponent com um @Input. Ou eu poderia usar um serviço compartilhado com assinaturas observáveis.
EDIT: Definir o item selecionado via evento + @Input não aciona o DetailComponent, no caso de eu precisar executar código adicional. Portanto, não tenho certeza se essa é uma solução aceitável.
Mas ambos os métodos parecem muito mais complexos do que a maneira Angular 1 de fazer as coisas, que era por meio de $ rootScope. $ Broadcast ou $ scope. $ Parent. $ Broadcast.
Como tudo no Angular 2 é um componente, estou surpreso que não haja mais informações disponíveis sobre a comunicação de componentes.
Existe outra maneira / mais simples de fazer isso?
fonte
Respostas:
Atualizado para rc.4: ao tentar passar dados entre componentes irmãos no angular 2, a maneira mais simples agora (angular.rc.4) é aproveitar a injeção de dependência hierárquica do angular2 e criar um serviço compartilhado.
Aqui estaria o serviço:
Agora, aqui estaria o componente PAI
e seus dois filhos
criança 1
criança 2 (é irmão)
AGORA: Coisas a serem observadas ao usar este método.
fonte
directives
não são mais declarados no componente.No caso de 2 componentes diferentes (componentes não aninhados, pai \ filho \ neto), sugiro o seguinte:
fonte
Uma maneira de fazer isso é usar um serviço compartilhado .
No entanto, acho a solução a seguir muito mais simples, ela permite compartilhar dados entre 2 irmãos. (Eu testei isso apenas no Angular 5 )
Em seu modelo de componente pai:
app-sibling2.component.ts
fonte
Há uma discussão sobre isso aqui.
https://github.com/angular/angular.io/issues/2663
A resposta de Alex J é boa, mas não funciona mais com o Angular 4 atual em julho de 2017.
E esse link de êmbolo demonstraria como se comunicar entre irmãos usando serviço compartilhado e observável.
https://embed.plnkr.co/P8xCEwSKgcOg07pwDrlO/
fonte
Uma diretiva pode fazer sentido em certas situações para 'conectar' componentes. Na verdade, as coisas que estão sendo conectadas nem precisam ser componentes completos e, às vezes, é mais leve e, na verdade, mais simples se não forem.
Por exemplo, eu tenho um
Youtube Player
componente (envolvendo a API do Youtube) e queria alguns botões de controle para ele. A única razão pela qual os botões não fazem parte do meu componente principal é que eles estão localizados em outro lugar no DOM.Nesse caso, é realmente apenas um componente de 'extensão' que só poderá ser usado com o componente 'pai'. Eu digo 'pai', mas no DOM é um irmão - então chame do que quiser.
Como eu disse, ele nem precisa ser um componente completo, no meu caso é apenas um
<button>
(mas pode ser um componente).No HTML para
ProductPage.component
, ondeyoutube-player
está obviamente meu componente que envolve a API do Youtube.A diretiva conecta tudo para mim, e não preciso declarar o evento (clique) no HTML.
Portanto, a diretiva pode se conectar perfeitamente ao reprodutor de vídeo sem ter que
ProductPage
ser um mediador.Esta é a primeira vez que realmente faço isso, então ainda não tenho certeza de como isso pode ser escalonável para situações muito mais complexas. Por isso estou feliz e deixa meu HTML simples e com responsabilidades de tudo distintas.
fonte
player
. Se eu deixar de fora a primeira menção de jogador, recebo um rangeError. Estou perplexo sobre como isso deve funcionar._player
para o campo privado que representa o jogador, então sim, você obteria um erro se copiasse isso exatamente. Atualizará. Desculpe!Aqui está uma explicação prática simples: Simplesmente explicado aqui
Em call.service.ts
Componente de onde você deseja chamar observável para informar outro componente que o botão foi clicado
Componente onde você deseja executar a ação no botão clicado em outro componente
Meu entendimento claro sobre a comunicação de componentes lendo isto: http://musttoknow.com/angular-4-angular-5-communicate-two-components-using-observable-subject/
fonte
O serviço compartilhado é uma boa solução para esse problema. Se você deseja armazenar algumas informações de atividade também, pode adicionar o serviço compartilhado à sua lista de provedores de módulos principais (app.module).
Depois, você pode fornecê-lo diretamente aos seus componentes,
Com o serviço compartilhado, você pode usar funções ou criar um assunto para atualizar vários locais de uma vez.
Em seu componente de lista, você pode publicar informações do item clicado,
e você pode buscar essas informações em seu componente de detalhe:
Obviamente, os dados que listam os compartilhamentos de componentes podem ser qualquer coisa. Espero que isto ajude.
fonte
Você precisa configurar a relação pai-filho entre seus componentes. O problema é que você pode simplesmente injetar os componentes filhos no construtor do componente pai e armazená-los em uma variável local. Em vez disso, você deve declarar os componentes filho em seu componente pai usando o
@ViewChild
declarador de propriedade. Esta é a aparência de seu componente pai: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
Cuidado, o componente filho não estará disponível no construtor do componente pai, logo após o
ngAfterViewInit
gancho do ciclo de vida ser chamado. Para pegar este ganchoAfterViewInit
, basta implementar a interface em sua classe pai da mesma maneira que você faria comOnInit
.Mas, existem outros declaradores de propriedade, conforme explicado nesta nota de blog: http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/
fonte
Assuntos de comportamento. Eu escrevi um blog sobre isso.
Neste exemplo, estou declarando um assunto de comportamento noid do tipo número. Também é um observável. E se "algo aconteceu", isso mudará com a função new () {}.
Então, nos componentes do irmão, um vai chamar a função, para fazer a mudança, e o outro será afetado por essa mudança, ou vice-versa.
Por exemplo, eu obtenho o id do URL e atualizo o noid do assunto de comportamento.
E por outro lado, posso perguntar se esse ID é "o que quer que eu queira" e fazer uma escolha depois disso, no meu caso se eu quero delte uma tarefa, e essa tarefa é o url atual, ela tem que me redirecionar para a casa:
fonte
Isso não é exatamente o que você quer, mas com certeza irá ajudá-lo
Estou surpreso que não haja mais informações por aí sobre comunicação de componentes <=> considere este tutorial de angualr2
Para comunicação de componentes irmãos, sugiro ir com
sharedService
. No entanto, também existem outras opções disponíveis.Consulte o link no topo para obter mais códigos.
Edit: Esta é uma pequena demonstração. Você já mencionou que já tentou
sharedService
. Portanto, considere este tutorial de angualr2 para obter mais informações.fonte
Tenho passado métodos setter do pai para um de seus filhos por meio de uma vinculação, chamando esse método com os dados do componente filho, o que significa que o componente pai é atualizado e pode então atualizar seu segundo componente filho com os novos dados. Requer vincular 'this' ou usar uma função de seta.
Isso tem a vantagem de que as crianças não estão tão acopladas umas às outras, pois não precisam de um serviço compartilhado específico.
Não estou totalmente certo de que esta seja a melhor prática, seria interessante ouvir a opinião de outros sobre isso.
fonte