web-dev-qa-db-fra.com

Angular 2 du routeur avec Observable

Après la sortie de Angular 2 RC.5, une résolution de routeur a été introduite. Ici exemple illustré avec Promise, comment faire de même si je fais une demande au serveur avec Observable?

search.service.ts

...
searchFields(id: number) {
  return this.http.get(`http://url.to.api/${id}`).map(res => res.json());
}
...

search-resol.service.ts

import { Injectable } from '@angular/core';
import { Router, Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';

import { SearchService } from '../shared';

@Injectable()
export class SearchResolveService implements Resolve<any> {

  constructor(
    private searchService: SearchService ,
    private router: Router
  ) {}

  resolve(route: ActivatedRouteSnapshot): Observable<any> | Promise<any> | any {
    let id = +route.params['id'];
    return this.searchService.searchFields(id).subscribe(fields => {
      console.log('fields', fields);
      if (fields) {
        return fields;
      } else { // id not found
        this.router.navigate(['/']);
        return false;
      }
    });
  }
}

search.component.ts

ngOnInit() {
  this.route.data.forEach((data) => {
    console.log('data', data);
  });
}

Obtenez Object {fields: Subscriber} au lieu de données réelles.

28
Rakhat

N'appelez pas subscribe() dans votre service et laissez plutôt la route s'abonner.

Changement

return this.searchService.searchFields().subscribe(fields => {

à

import 'rxjs/add/operator/first' // in imports

return this.searchService.searchFields().map(fields => {
  ...
}).first();

De cette façon, un Observable est retourné au lieu d'un Subscription (qui est retourné par subscribe()).

Actuellement, le routeur attend la fermeture de l'observable. Vous pouvez vous assurer qu'il se ferme après l'émission de la première valeur, en utilisant l'opérateur first().

49
Günter Zöchbauer