pasar parametros otro enviar entre ejemplo datos comunicacion componentes componente angular typescript

parametros - ¿Cómo paso datos a componentes enrutados angulares?



pasar datos entre componentes angular 5 (11)

Angular 7.2.0 introdujo una nueva forma de pasar los datos al navegar entre componentes enrutados:

<a routerLink = "/link" [queryParams] = "{parameterName: objectToPass| json }"> sample Link </a>

O:

@Component({ template: `<a (click)="navigateWithState()">Go</a>`, }) export class AppComponent { constructor(public router: Router) {} navigateWithState() { this.router.navigateByUrl(''/123'', { state: { hello: ''world'' } }); } }

Para leer el estado, puede acceder a la propiedad window.history.state después de que la navegación haya finalizado:

@Component({ selector: ''my-app'', template: ` <a routerLink="/details" [state]="{ hello: ''world'' }">Go</a>`, }) export class AppComponent {}

En una de las plantillas de mis rutas de Angular 2 ( FirstComponent ) tengo un botón

first.component.html

<div class="button" click="routeWithData()">Pass data and route</div>

Mi objetivo es lograr:

Haga clic en el botón -> diríjase a otro componente mientras conserva los datos y sin usar el otro componente como directiva.

Esto es lo que probé ...

1er ENFOQUE

En la misma vista, estoy almacenando la recopilación de los mismos datos en función de la interacción del usuario.

first.component.ts

export class FirstComponent { constructor(private _router: Router) { } property1: number; property2: string; property3: TypeXY; // this a class, not a primitive type // here some class methods set the properties above // DOM events routeWithData(){ // here route } }

Normalmente me dirigiría a SecondComponent por

this._router.navigate([''SecondComponent'']);

eventualmente pasando los datos por

this._router.navigate([''SecondComponent'', {p1: this.property1, p2: property2 }]);

mientras que la definición del enlace con parámetros sería

@RouteConfig([ // ... { path: ''/SecondComponent/:p1:p2'', name: ''SecondComponent'', component: SecondComponent} )]

El problema con este enfoque es que supongo que no puedo pasar datos complejos (por ejemplo, un objeto como propiedad3) en la URL;

2º ENFOQUE

Una alternativa sería incluir SecondComponent como directiva en FirstComponent.

<SecondComponent [p3]="property3"></SecondComponent>

Sin embargo, quiero enrutar a ese componente, ¡no incluirlo!

3er ENFOQUE

La solución más viable que veo aquí sería usar un Servicio (por ejemplo, FirstComponentService) para

  • almacenar los datos (_firstComponentService.storeData ()) en routeWithData () en FirstComponent
  • recuperar los datos (_firstComponentService.retrieveData ()) en ngOnInit () en SecondComponent

Si bien este enfoque parece perfectamente viable, me pregunto si esta es la forma más fácil / elegante de lograr el objetivo.

En general, me gustaría saber si me faltan otros enfoques potenciales para pasar los datos entre componentes, particularmente con la menor cantidad de código posible


Creo que dado que no tenemos el tipo de cosa $ rootScope en angular 2 como en angular 1.x. Podemos usar el servicio / clase angular 2 mientras que en ngOnDestroy pase los datos al servicio y, después del enrutamiento, tomemos los datos del servicio en la función ngOnInit :

Aquí estoy usando DataService para compartir el objeto héroe:

import { Hero } from ''./hero''; export class DataService { public hero: Hero; }

Pase el objeto del primer componente de la página:

ngOnDestroy() { this.dataService.hero = this.hero; }

Tomar objeto del componente de la segunda página:

ngOnInit() { this.hero = this.dataService.hero; }

Aquí hay un ejemplo: plunker


El tercer enfoque es la forma más común de compartir datos entre componentes. puede inyectar el servicio del elemento que desea usar en un componente relacionado.

goToPage(pageNum) { this.router.navigate([''/product-list''], { queryParams: { serviceId: serviceId} }); }


Este otro enfoque no es bueno para este problema. Creo que el mejor enfoque es Query-Parameter by Router angular que tiene 2 vías:

Pasando el parámetro de consulta directamente

Con este código puede navegar a url por params en su código html:

import { Injectable } from ''@angular/core''; import { Predicate } from ''../interfaces'' import * as _ from ''lodash''; @Injectable() export class ItemsService { constructor() { } removeItemFromArray<T>(array: Array<T>, item: any) { _.remove(array, function (current) { //console.log(current); return JSON.stringify(current) === JSON.stringify(item); }); } removeItems<T>(array: Array<T>, predicate: Predicate<T>) { _.remove(array, predicate); } setItem<T>(array: Array<T>, predicate: Predicate<T>, item: T) { var _oldItem = _.find(array, predicate); if(_oldItem){ var index = _.indexOf(array, _oldItem); array.splice(index, 1, item); } else { array.push(item); } } addItemToStart<T>(array: Array<T>, item: any) { array.splice(0, 0, item); } getPropertyValues<T, R>(array: Array<T>, property : string) : R { var result = _.map(array, property); return <R><any>result; } getSerialized<T>(arg: any): T { return <T>JSON.parse(JSON.stringify(arg)); } } export interface Predicate<T> { (item: T): boolean }

Pasar parámetro de consulta por Router

Tienes que inyectar el enrutador dentro de tu constructor como:

export class AdminUserListComponent { users : User[]; constructor( private router : Router) { } modifyUser(i) { let navigationExtras: NavigationExtras = { queryParams: { "user": JSON.stringify(this.users[i]) } }; this.router.navigate(["admin/user/edit"], navigationExtras); } }

Ahora use eso como:

export class AdminUserEditComponent { userWithRole: UserWithRole; constructor( private route: ActivatedRoute) {} ngOnInit(): void { super.ngOnInit(); this.route.queryParams.subscribe(params => { this.userWithRole.user = JSON.parse(params["user"]); }); } }

Ahora, si desea leer desde el Router en otro Component , debe usar ActivatedRoute como:

<a [routerLink]="[''customer-service'']" [queryParams]="{ serviceId: 99 }"></a>

y subscribe que:

constructor(private router:Router){ }


Pase usando JSON

export class PageComponent implements OnInit { state$: Observable<object>; constructor(public activatedRoute: ActivatedRoute) {} ngOnInit() { this.state$ = this.activatedRoute.paramMap .pipe(map(() => window.history.state)) } }


Solución con ActiveRoute (si desea pasar un objeto por ruta, use JSON.stringfy / JSON.parse):

Prepare el objeto antes de enviarlo:

constructor(private activateRouter:ActivatedRouter){ }

Reciba su objeto en el componente de destino:

ngOnInit() { this.sub = this.route .queryParams .subscribe(params => { // Defaults to 0 if no query param provided. this.page = +params[''serviceId''] || 0; }); }


Una persona súper inteligente (tmburnell) que no soy yo sugiere reescribir los datos de la ruta:

let route = this.router.config.find(r => r.path === ''/path''); route.data = { entity: ''entity'' }; this.router.navigateByUrl(''/path'');

Como se ve here en los comentarios.

Espero que alguien encuentre esto útil


di que tienes

  1. component1.ts
  2. componente1.html

y desea pasar datos a component2.ts .

  • en component1.ts es una variable con datos que dicen

    //component1.ts item={name:"Nelson", bankAccount:"1 million dollars"} //component1.html //the line routerLink="/meter-readings/{{item.meterReadingId}}" has nothing to //do with this , replace that with the url you are navigating to <a mat-button [queryParams]="{ params: item | json}" routerLink="/meter-readings/{{item.meterReadingId}}" routerLinkActive="router-link-active"> View </a> //component2.ts import { ActivatedRoute} from "@angular/router"; import ''rxjs/add/operator/filter''; /*class name etc and class boiler plate */ data:any //will hold our final object that we passed constructor( private route: ActivatedRoute, ) {} ngOnInit() { this.route.queryParams .filter(params => params.reading) .subscribe(params => { console.log(params); // DATA WILL BE A JSON STRING- WE PARSE TO GET BACK OUR //OBJECT this.data = JSON.parse(params.item) ; console.log(this.data,''PASSED DATA''); //Gives {name:"Nelson", bankAccount:"1 //million dollars"} }); }


use un servicio compartido para almacenar datos con un índice personalizado. luego envíe ese índice personalizado con queryParam. Este enfoque es más flexible .

// component-a : typeScript : constructor( private DataCollector: DataCollectorService ) {} ngOnInit() { this.DataCollector[''someDataIndex''] = data; } // component-a : html : <a routerLink="/target-page" [queryParams]="{index: ''someDataIndex''}"></a>

.

// component-b : typeScript : public data; constructor( private DataCollector: DataCollectorService ) {} ngOnInit() { this.route.queryParams.subscribe( (queryParams: Params) => { this.data = this.DataCollector[queryParams[''index'']]; } ); }


actualización 4.0.0

Ver documentos angulares para más detalles https://angular.io/guide/router#fetch-data-before-navigating

original

Usar un servicio es el camino a seguir. En los parámetros de ruta, solo debe pasar los datos que desea que se reflejen en la barra de URL del navegador.

Ver también https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

El enrutador enviado con RC.4 reintroduce data

constructor(private route: ActivatedRoute) {}

const routes: RouterConfig = [ {path: '''', redirectTo: ''/heroes'', pathMatch : ''full''}, {path : ''heroes'', component : HeroDetailComponent, data : {some_data : ''some value''}} ];

class HeroDetailComponent { ngOnInit() { this.sub = this.route .data .subscribe(v => console.log(v)); } ngOnDestroy() { this.sub.unsubscribe(); } }

Vea también el Plunker en https://github.com/angular/angular/issues/9757#issuecomment-229847781


<div class="button" click="routeWithData()">Pass data and route</div>

bueno, la forma más fácil de hacerlo en angular 6 u otras versiones, espero es simplemente definir su ruta con la cantidad de datos que desea pasar

{path: ''detailView/:id'', component: DetailedViewComponent}

Como puede ver en mi definición de rutas, agregué el /:id para soportar los datos que quiero pasar al componente a través de la navegación del enrutador. Por lo tanto, su código se verá así

<a class="btn btn-white-view" [routerLink]="[ ''/detailView'',list.id]">view</a>

para leer la id en el componente, simplemente importe ActivatedRoute como

import { ActivatedRoute } from ''@angular/router''

y en el ngOnInit es donde recuperas los datos

ngOnInit() { this.sub = this.route.params.subscribe(params => { this.id = params[''id'']; }); console.log(this.id); }

Puedes leer más en este artículo https://www.tektutorialshub.com/angular-passing-parameters-to-route/