Envie dados pelos caminhos de roteamento no Angular

181

Existe alguma maneira de enviar dados como parâmetro com router.navigate? Quero dizer, algo como este exemplo, como você pode ver a rota tem um parâmetro de dados, mas fazer isso não está funcionando:

this.router.navigate(["heroes"], {some-data: "othrData"})

porque some-data não é um parâmetro válido. Como eu posso fazer isso? Não quero enviar o parâmetro com queryParams.

Motomine
fonte
Eu acho que deveria ser de outra maneira, como no AngularJS, onde fomos capazes de fazer algo como $ state.go ('heroes', {some-data: "otherData"})
Motomine
3 maneiras simples de compartilhar dados através de rotas - angulartutorial.net/2017/12/…
Prashobh
Use minha abordagem npmjs.com/package/ngx-navigation-with-data ultimo comentário por mim, melhor para todos #
Virendra Yadav

Respostas:

512

Há muita confusão sobre esse tópico porque existem muitas maneiras diferentes de fazer isso.

Aqui estão os tipos apropriados usados ​​nas seguintes capturas de tela:

private route: ActivatedRoute
private router: Router

1) Parâmetros de roteamento necessários:

insira a descrição da imagem aqui

2) Parâmetros opcionais da rota:

insira a descrição da imagem aqui

3) Parâmetros de consulta de rota:

insira a descrição da imagem aqui

4) Você pode usar um serviço para passar dados de um componente para outro sem usar parâmetros de rota.

Para obter um exemplo, consulte: https://blogs.msmvps.com/deborahk/build-a-simple-angular-service-to-share-data/

Eu tenho um plunker disso aqui: https://plnkr.co/edit/KT4JLmpcwGBM2xdZQeI9?p=preview

DeborahK
fonte
Obrigado pela sua resposta! Qual é a diferença entre o 2) e o 3)? Porque ambos acabam adicionando "? Parameter =" no URL. Você poderia me dar um exemplo para o 4)? Não consigo descobrir como fazê-lo.
Motomine
Atualizei por resposta para mostrar os diferentes URLs e fornecer um link para uma postagem no blog e mais informações sobre como passar dados com um serviço. O URL é diferente com os parâmetros opcionais e de consulta, como mostrado acima. Além disso, os parâmetros de consulta podem ser mantidos nas rotas.
DeborahK
5
Também tenho um curso da Pluralsight sobre roteamento que abrange tudo isso: app.pluralsight.com/library/courses/rural-routing/… Você pode se inscrever por uma semana grátis se estiver interessado em mais informações.
DeborahK
3
Os dados são apenas "compartilhados" dentro do aplicativo em execução. Se o usuário atualizar a página, o aplicativo inteiro será recarregado do servidor, portanto, nenhum estado anterior será mantido no aplicativo. Pensar nisso em termos de um aplicativo normal, quando um usuário atualiza, é como fechar e reabrir o aplicativo. Se você precisar reter o estado após uma atualização, precisará armazená-lo em algum lugar, como armazenamento local ou no servidor.
DeborahK
2
Apenas uma pequena dica: o routetipo é ActivatedRoute, não Router.
Arsen Khachaturyan
156

Existe um novo método que veio com o Angular 7.2.0

https://angular.io/api/router/NavigationExtras#state

Enviar:

this.router.navigate(['action-selection'], { state: { example: 'bar' } });

Receber:

constructor(private router: Router) {
  console.log(this.router.getCurrentNavigation().extras.state.example); // should log out 'bar'
}

Você pode obter algumas informações adicionais aqui:

https://github.com/angular/angular/pull/27198

O link acima contém este exemplo, o que pode ser útil: https://stackblitz.com/edit/angular-bupuzn

Véger Lóránd
fonte
11
Esta é a resposta correta, dadas as novas funcionalidades do angular 7.
Randy
2
Com essa abordagem, como eu lidaria com uma atualização do navegador pelo usuário? Nesse caso, os dados nos extras de navegação parecem desaparecer, portanto não há chance de usá-los novamente na atualização.
tobi_b 6/02/19
1
@tobi_b Eu acho que você está certo, após a atualização você não pode alcançá-lo. Se você precisar após a atualização, os métodos na resposta aceita serão melhores.
Véger Lóránd 12/02/19
3
Sim, é por isso que você só pode obter os dados do this.router.getCurrentNavigation () no construtor. Se você precisar em outro lugar, como dentro do ngOnInit (), poderá acessar os dados através de "history.state". Na documentação: "Estado passado para qualquer navegação. Este valor estará acessível através do objeto extra retornado pelo router.getCurrentNavigation () enquanto uma navegação estiver em execução. Quando a navegação for concluída, esse valor será gravado em history.state quando o local O método .go ou location.replaceState é chamado antes de ativar esta rota. "
Véger Lóránd 01/04/19
8
Também certifique-se que você não tente para receber um objeto extras em ngOnInit()comothis.router.getCurrentNavigation().extras
hastrb
26

A versão mais recente do angular (7.2 +) agora tem a opção de passar informações adicionais usando o NavigationExtras .

Componente inicial

import {
  Router,
  NavigationExtras
} from '@angular/router';
const navigationExtras: NavigationExtras = {
  state: {
    transd: 'TRANS001',
    workQueue: false,
    services: 10,
    code: '003'
  }
};
this.router.navigate(['newComponent'], navigationExtras);

newComponent

test: string;
constructor(private router: Router) {
  const navigation = this.router.getCurrentNavigation();
  const state = navigation.extras.state as {
    transId: string,
    workQueue: boolean,
    services: number,
    code: string
  };
  this.test = "Transaction Key:" + state.transId + "<br /> Configured:" + state.workQueue + "<br /> Services:" + state.services + "<br /> Code: " + state.code;
}

Resultado

insira a descrição da imagem aqui

Espero que isso ajude!

dev-nish
fonte
1

@ dev-nish Seu código funciona com pequenos ajustes neles. faça o

const navigationExtras: NavigationExtras = {
  state: {
    transd: 'TRANS001',
    workQueue: false,
    services: 10,
    code: '003'
  }
};

para dentro

let navigationExtras: NavigationExtras = {
  state: {
    transd: '',
    workQueue: ,
    services: ,
    code: ''
  }
};

se desejar enviar especificamente um tipo de dados, por exemplo, JSON como resultado de um preenchimento de formulário, você poderá enviar os dados da mesma maneira como explicado anteriormente.

Saurav Mohan V
fonte
0

Em navigateExtra, podemos passar apenas algum nome específico como argumento, caso contrário, ele mostra um erro como abaixo: Por exemplo, aqui quero passar a chave do cliente no roteador navigate e passo assim-

this.Router.navigate(['componentname'],{cuskey: {customerkey:response.key}});

mas mostrando algum erro como abaixo:

Argument of type '{ cuskey: { customerkey: any; }; }' is not assignable to parameter of type 'NavigationExtras'.
  Object literal may only specify known properties, and 'cuskey' does not exist in type 'NavigationExt## Heading ##ras'

.

Solução: temos que escrever assim:

this.Router.navigate(['componentname'],{state: {customerkey:response.key}});
A. PRABIN SARAB
fonte
-2

O melhor que encontrei na internet para isso é o ngx-navigation-with-data . É muito simples e bom para navegar nos dados de um componente para outro. Você precisa apenas importar a classe de componente e usá-la de maneira muito simples. Suponha que você tenha um componente residencial e sobre o qual deseja enviar dados.

COMPONENTE EM CASA

import { Component, OnInit } from '@angular/core';
import { NgxNavigationWithDataComponent } from 'ngx-navigation-with-data';

@Component({
 selector: 'app-home',
 templateUrl: './home.component.html',
 styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

constructor(public navCtrl: NgxNavigationWithDataComponent) { }

 ngOnInit() {
 }

 navigateToABout() {
  this.navCtrl.navigate('about', {name:"virendta"});
 }

}

SOBRE O COMPONENTE

import { Component, OnInit } from '@angular/core';
import { NgxNavigationWithDataComponent } from 'ngx-navigation-with-data';

@Component({
 selector: 'app-about',
 templateUrl: './about.component.html',
 styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {

 constructor(public navCtrl: NgxNavigationWithDataComponent) {
  console.log(this.navCtrl.get('name')); // it will console Virendra
  console.log(this.navCtrl.data); // it will console whole data object here
 }

 ngOnInit() {
 }

}

Para qualquer consulta, siga https://www.npmjs.com/package/ngx-navigation-with-data

Comente para obter ajuda.

Virendra Yadav
fonte
Transfere dados na forma de parâmetros ou apenas em segundo plano?
Marium Malik
Eu não conseguia entender @MariumMalik Você pode perguntar de forma descritiva?
Virendra Yadav
@MariumMalik
Virendra Yadav
3
Você parece ser o autor disso, em vez de "eu encontrei na internet"? Você também está sendo solicitado a não enviá -lo por spam no encadeamento do Angular 7 que implementa funcionalidade semelhante ( github.com/angular/angular/pull/27198 ) #
IrishDubGuy