Eu tenho um componente pai que vai para o servidor e busca um objeto:
// parent component
@Component({
selector : 'node-display',
template : `
<router-outlet [node]="node"></router-outlet>
`
})
export class NodeDisplayComponent implements OnInit {
node: Node;
ngOnInit(): void {
this.nodeService.getNode(path)
.subscribe(
node => {
this.node = node;
},
err => {
console.log(err);
}
);
}
E em uma das várias telas infantis:
export class ChildDisplay implements OnInit{
@Input()
node: Node;
ngOnInit(): void {
console.log(this.node);
}
}
Não parece que posso simplesmente injetar dados no router-outlet
. Parece que recebo o erro no console da web:
Can't bind to 'node' since it isn't a known property of 'router-outlet'.
Isso faz sentido, mas como eu faria o seguinte:
- Pegue os dados do "nó" do servidor, de dentro do componente pai?
- Passar os dados que recuperei do servidor para a tomada do roteador filho?
Não parece router-outlets
funcionar da mesma maneira.
node
onde está como um tipostring
e não parece funcionar ou estou fazendo algo erradoElementRef
de um evento na saída do roteador para usá-lo para definir o id, mas não sei de cor se ou como fazer isso (apenas no meu telefone)A resposta de Günters é ótima, só quero apontar outra maneira sem usar Observáveis.
Aqui, porém, devemos lembrar que esses objetos são passados por referência, então se você quiser fazer algum trabalho no objeto da criança e não afetar o objeto pai, eu sugeriria usar a solução de Günther. Mas se isso não importa ou realmente é o comportamento desejado , sugiro o seguinte.
Em seu pai, você pode atribuir o valor:
E em seus filhos (E pai), injete o serviço compartilhado em seu construtor. Lembre-se de fornecer o serviço na matriz de provedores de nível de módulo se desejar um serviço singleton em todos os componentes desse módulo. Como alternativa, basta adicionar o serviço na matriz de provedores apenas no pai , então o pai e o filho compartilharão a mesma instância de serviço.
E como newman gentilmente apontou, você também pode ter
this.sharedService.sharedNode
no template html ou um getter:fonte
Sim, você pode definir entradas de componentes exibidos por meio de saídas do roteador . Infelizmente, você precisa fazer isso de forma programática, conforme mencionado em outras respostas. Há uma grande advertência quando os observáveis estão envolvidos (descrito abaixo).
Veja como:
(1) Conecte-se ao
activate
evento da tomada do roteador no modelo pai:(2) Mude para o arquivo de texto digitado do pai e defina as entradas do componente filho programaticamente sempre que forem ativados:
A versão acima do
onOutletLoaded
é simplificada para maior clareza, mas só funciona se você puder garantir que todos os componentes filhos tenham exatamente as mesmas entradas que você está atribuindo. Se você tiver componentes com entradas diferentes, use protetores de tipo:Por que esse método pode ser preferido ao método de serviço?
Nem esse método nem o método de serviço são "a maneira certa" de se comunicar com os componentes filhos (ambos os métodos se distanciam da associação de modelo pura), portanto, você só precisa decidir qual forma parece mais apropriada para o projeto.
Esse método, entretanto, permite que você evite fazer o objeto intermediário (o serviço), que une fortemente o serviço e os componentes filho. Em muitos casos, isso parece mais "angular" porque você pode continuar passando dados para seus componentes filhos por meio de @Inputs. Também é uma boa opção para componentes já existentes ou de terceiros que você não deseja ou não pode unir fortemente a esse serviço. Por outro lado, pode parecer menos angular quando ...
Embargo
A ressalva com este método é que, uma vez que você está passando dados programaticamente, você não tem mais a opção de passar dados observáveis em seu modelo (surpresa!). Isso significa que você perde a grande vantagem do gerenciamento angular do ciclo de vida do observável para você ao usar o padrão de pipe assíncrono.
Em vez disso, você precisará configurar algo para obter os valores observáveis atuais sempre que a
onChildLoaded
função for chamada. Isso provavelmente também exigirá alguma desmontagem naonDestroy
função do componente pai . Isso não é nada incomum, há outros casos em que isso precisa ser feito, como ao usar um observável que nem chega ao modelo.fonte
Serviço:
Componente:
fonte
Existem 3 maneiras de passar dados dos pais para os filhos
Através do Children Router Resolver se você tiver que receber dados diferentes
Por meio do Resolvedor do Roteador Pai, caso precise receber os mesmos dados dos pais
Nota 1: você pode ler sobre o resolvedor aqui . Também há um exemplo de resolvedor e como registrar o resolvedor no módulo e, em seguida, recuperar dados do resolvedor para o componente. O registro do resolvedor é o mesmo no pai e no filho.
Nota 2: Você pode ler sobre ActivatedRoute aqui para poder obter dados do roteador
fonte
Seguindo esta pergunta, no Angular 7.2 você pode passar dados de pai para filho usando o estado do histórico. Então você pode fazer algo como
Mas tome cuidado para ser consistente. Por exemplo, suponha que você deseja exibir uma lista em uma barra do lado esquerdo e os detalhes do item selecionado à direita usando uma tomada de roteador. Algo como:
Item 1 (x) | ..............................................
Item 2 (x) | ...... Detalhes do item selecionado .......
Item 3 (x) | ..............................................
Item 4 (x) | ..............................................
Agora, suponha que você já tenha clicado em alguns itens. Clicar nos botões de voltar do navegador exibirá os detalhes do item anterior. Mas e se, enquanto isso, você clicar no (x) e excluir esse item da sua lista? Em seguida, clicar em voltar mostra os detalhes de um item excluído.
fonte