web-dev-qa-db-fra.com

Utilisation de Resolve dans les itinéraires Angular2

Dans Angular 1 ma configuration ressemble à ceci:

$routeProvider
  .when("/news", {
    templateUrl: "newsView.html",
    controller: "newsController",
    resolve: {
        message: function(messageService){
            return messageService.getMessage();
    }
  }
})

Comment utiliser Solve dans Angular2?

31
Kyle

@ La réponse d'AndréWerlang était bonne, mais si vous voulez que les données résolues sur la page changent lorsque le paramètre d'itinéraire change , vous devez:

Résolveur:

@Injectable()
export class MessageResolver implements Resolve<Message> {

  constructor(private messageService: MessageService, private router: Router) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Message> {
    const id = +route.params['id'];
    return this.messageService.getById(id);
  }
}

Votre composant:

ngOnInit() {
  this.route.data.subscribe((data: { message: Message }) => {
    this.message = data.message;
  });
}
4
Steve Brush

Basé sur @ angular/router v3-beta, ce sont les étapes requises.

Implémentez un résolveur qui renvoie une valeur observable ou simple:

@Injectable()
export class HeroResolver implements Resolve {

    constructor(
        private service: HeroService
    ) {}

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Hero> {
        const id = +route.params['id'];
        return Observable.fromPromise(this.service.getHero(id));
    }

}

Notez que si vous retournez un observable, la valeur déballée (la première) sera disponible via route.snapshot.data. Si vous voulez que l'observable lui-même soit disponible, vous devez l'envelopper dans un autre observable:

return Observable.of(source$);

Ajoutez le résolveur à votre itinéraire:

export const HeroesRoutes: RouterConfig = [
    { path: 'heroes',  component: HeroListComponent, resolve: { heroes: HeroesResolver } },
    { path: 'hero/:id', component: HeroDetailComponent, resolve: { hero: HeroResolver } }
];

Enfin, fournissez votre classe de résolution et toute dépendance à bootstrap ou votre composant principal providers:

bootstrap(AppComponent, [
    HeroesResolver, HeroService
])

Consommez les données résolues d'une instance ActivatedRoute:

ngOnInit() {
    this.hero = this.route.snapshot.data['hero'];
}

N'oubliez pas que l'instantané signifie la valeur à l'état d'exécution, à la fois dans la classe de composant et la classe de résolveur. Les données ne peuvent pas être actualisées à partir des mises à jour des paramètres avec cette approche.

Plunker: http://plnkr.co/edit/jpntLjrNOgs6eSFp1j1P?p=preview Matière source: https://github.com/angular/angular/commit/f2f1ec0#diff-a19f4d51bb98289ab777640d9e8e5006

28
André Werlang

Comme les alexpods l'ont déjà mentionné, il ne semble pas y avoir de "résolution" en tant que telle. L'idée semble être que vous utilisez les crochets de cycle de vie fournis par le routeur. Ceux-ci sont:

  • canReuse
  • canDeactivate
  • onActivate
  • onReuse
  • onDeactivate

Ensuite, il y a @ CanActivate. Il s'agit d'un hook spécial car il est appelé avant l'instanciation de votre composant. Ses paramètres sont (next, previous) qui sont les composants vers lesquels vous routez et le composant dont vous venez (ou null si vous n'avez pas d'historique) respectivement.

import {Component} from '@angular/core';
import {ROUTER_DIRECTIVES, CanActivate, OnActivate} from '@angular/router';

@Component({
    selector: 'news',
    templateUrl: 'newsView.html',
    directives: [ROUTER_DIRECTIVES]
})

@CanActivate((next) => {
    return messageService.getMessage()
        .then((message) => {
            next.params.message = message;
            return true; //truthy lets route continue, false stops routing
        });
})

export class Accounts implements OnActivate {

    accounts:Object;

    onActivate(next) {
        this.message = next.params.message;
    }
}

La chose que je n'ai pas encore trouvée est de savoir comment obtenir le résultat de la promesse dans votre onActivate - autre que le stocker sur votre "prochain" composant. En effet, onActivate est également uniquement invoqué avec suivant et précédent et non le résultat de la promesse. Je ne suis pas satisfait de cette solution mais c'est le mieux que j'ai pu trouver.

28
Paysdoc

https://angular.io/docs/ts/latest/api/router/index/Resolve-interface.html "résoudre" a été ramené au routeur angular2, mais la documentation est rare.

Exemple:

class TeamResolver implements Resolve {
  constructor(private backend: Backend) {}
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<any> {
    return this.backend.fetchTeam(this.route.params.id);
  }
}
bootstrap(AppComponent, [
  TeamResolver,
  provideRouter([{
    path: 'team/:id',
    component: TeamCmp,
    resolve: {
      team: TeamResolver
    }
  }])
);
9
Vitali Kniazeu

Vous pouvez créer votre Resolver dans Angular2 + et l'appliquer au routeur assez facilement. regardez ci-dessous, voici la façon de créer le résolveur en angulaire:

@Injectable()
export class AboutResolver implements Resolve<Message> {

  constructor(private aboutService: AboutService, private router: Router) {}

  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
    const id = route.params['id'];
    return this.aboutService.getById(id);
  }
}

puis dans la configuration du routeur:

export const Routes: RouterConfig = [
  { path: 'about',  component: AboutComponent, resolve: { data: AboutResolver } }
]; 

et enfin dans votre composant:

ngOnInit() {
  this.route.data.subscribe((data: { about: About }) => {
    this.about = data.about;
  });
}
5
Alireza