web-dev-qa-db-fra.com

Passer des données dynamiques à travers Angular 2 parcours

Il est possible de transmettre des données statiques à une route Angular 2 sans les afficher sur l'URL.

Mais comment puis-je transmettre dynamic data/object de la même manière?

7
Kaleab

Vous pouvez utiliser un résolveur. Les données renvoyées par un résolveur sont mises à la disposition des routes de la même manière que la variable statique data dans les configurations de route

Pour un exemple, voir https://angular.io/docs/ts/latest/guide/router.html#!#resolve-guard

@Injectable()
export class CrisisDetailResolve implements Resolve<Crisis> {
  constructor(private cs: CrisisService, private router: Router) {}
  resolve(route: ActivatedRouteSnapshot): Promise<Crisis>|boolean {
    let id = route.params['id'];
    return this.cs.getCrisis(id).then(crisis => {
      if (crisis) {
        return crisis;
      } else { // id not found
        this.router.navigate(['/crisis-center']);
        return false;
      }
    });
  }
}
path: '',
component: CrisisListComponent,
children: [
  {
    path: ':id',
    component: CrisisDetailComponent,
    canDeactivate: [CanDeactivateGuard],
    resolve: {
      crisis: CrisisDetailResolve
    }
  },
ngOnInit() {
  this.route.data
    .subscribe((data: { crisis: Crisis }) => {
      this.editName = data.crisis.name;
      this.crisis = data.crisis;
    });
}
4
Günter Zöchbauer

Il est préférable de combiner les deux réponses précédentes:

  • Le answer de Günter Zöchbauer consiste en un résolveur personnalisé qui est un enricher en-message : une URL se terminant par /crisis/15, il transmettra toutes les données de la crise au composant de crise. Nous avons besoin du résolveur, mais je pense que OP ne voulait pas que des données apparaissent dans l'URL.
  • Tsadkan Yitbarek answer propose un service de stockage de données et de communication (similaire à un magasin dans Redux/Flux). Il pense à juste titre que c'est exagéré, mais nous devons stocker les informations quelque part.

La solution consiste donc à placer les données partagées dans le résolveur lui-même: contrairement aux composants, les services ont une longue durée de vie et ne comportent toujours qu’une instance, de sorte que les données sont en sécurité dans le résolveur:

// --- CrisisDetailResolve --- 
// In the function body, add:
private currentCrisisId: number | string

set(crisisId: number | string) {
   this.currentCrisisId = crisisId 
}

// change line 5 of CrisisDetailResolve:
 let id: number = 0 + this.currentCrisisId

// -- In your code -- 
// You can now navigate while hiding 
// the crisis number from the user:
private click(crisisId : string | number) {
  // tell resolver about the upcoming crisis:
  this.crisisResolve.set(crisisId)  
  // navigate to CrisisDetail, via CrisisResolve:
  this.router.navigate(['/crisisDetail')
  // CrisisDetail can now receive id and name in its NgOnInit via `data`,
  // as in Günter Zöchbauer's answer and the Angular docs 
}

Voir aussi Angular Docs sur le routage

1
dirkjot

Vous pouvez faire deux choses 1.Non recommandé mais utiliser les données comme paramètre de routeur et passer,

{ path: 'some:data', component: SomeComonent }

et utiliser comme 

let data = {"key":"value"}
this.router.navigate(['/some', data)

2.Au lieu de passer des données à travers des paramètres de route (car les données peuvent être énormes et également vulnérables aux attaques car elles peuvent être visualisées par l'utilisateur)

@Injectable()
export class SomeService {
  data = {};
}

@Component({...
   providers: [SomeService]
export class Parent {
  constructor(private someService:SomeService) {}

  private click() {
    this.someService.data = {"key":"value"}
  }
}
1
tsadkan yitbarek