Come posso passare i dati a componenti indirizzati angolari?

In uno dei miei modelli di percorsi Angular 2 ( FirstComponent ) ho un pulsante

first.component.html

Pass data and route

Il mio objective è raggiungere:

Fare clic con il pulsante -> instradare a un altro componente preservando i dati e senza utilizzare l’altro componente come direttiva.

Questo è quello che ho provato …

1 ° APPROCCIO

Nella stessa vista sto memorizzando la raccolta degli stessi dati in base all’interazione dell’utente.

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 andrei su SecondComponent da

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

infine passare i dati da

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

mentre la definizione del legame con i parametri sarebbe

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

Il problema con questo approccio è che immagino di non poter passare dati complessi (ad es. Un object come property3) in-url;

2 ° APPROCCIO

Un’alternativa includerebbe SecondComponent come direttiva in FirstComponent.

   

Tuttavia, voglio indirizzare a quel componente, non includerlo!

3 ° APPROCCIO

La soluzione più praticabile che vedo qui sarebbe quella di utilizzare un servizio (ad esempio FirstComponentService) per

  • memorizzare i dati (_firstComponentService.storeData ()) su routeWithData () in FirstComponent
  • recuperare i dati (_firstComponentService.retrieveData ()) in ngOnInit () in SecondComponent

Mentre questo approccio sembra perfettamente fattibile, mi chiedo se questo sia il modo più semplice / elegante per raggiungere l’objective.

In generale mi piacerebbe sapere se mi mancano altri potenziali approcci per passare i dati tra i componenti, in particolare con la minore quantità ansible di codice

aggiornamento 4.0.0

Vedi documenti angolari per maggiori dettagli https://angular.io/guide/router#fetch-data-before-navigating

originale

Usare un servizio è la strada da percorrere. Nei parametri di instradamento devi solo passare i dati che desideri vengano riflessi nella barra degli indirizzi del browser.

Vedi anche https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

Il router fornito con RC.4 reintroduce i 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(); } } 

Vedi anche il Plunker su https://github.com/angular/angular/issues/9757#issuecomment-229847781

Penso che dal momento che non abbiamo il tipo di object rootScope $ nell’angular 2 come nell’angular 1.x. Possiamo utilizzare il servizio / class condivisa angular 2 mentre in ngOnDestroy passiamo i dati al servizio e dopo il routing prendiamo i dati dal servizio nella funzione ngOnInit :

Qui sto usando DataService per condividere l’object eroe:

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

Passa object dal componente della prima pagina:

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

Prendi l’object dal componente della seconda pagina:

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

Ecco un esempio: plunker

Il terzo approccio è il modo più comune per condividere i dati tra i componenti. è ansible iniettare il servizio articolo che si desidera utilizzare nel componente correlato.

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

Passa usando JSON

   sample Link