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.
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()
.