web-dev-qa-db-fra.com

Angular 2.0.2: ActivatedRoute est vide dans un service

Je souhaite utiliser ActivatedRoute pour obtenir des paramètres de route dans un service, comme je le ferais dans un composant . Toutefois, lorsque j'injecte l'objet ActivatedRoute dans un service, il contient une variable de paramètre vide.

J'ai créé un lecteur qui reproduit le comportement suivant: http://plnkr.co/edit/sckmDYnpIlZUbqqB3gli

Notez que l'intention est d'utiliser le paramètre dans le service et non dans le composant, la façon dont le plongeur est configuré sert uniquement à démontrer le problème.

Composant (test est récupéré):

export class Component implements OnInit {
  result: string;

  constructor(private route: ActivatedRoute) {
  }

  ngOnInit() {
    this.route.params.subscribe(params => {
      this.result = params['test'];
    });
  }
}

Service (test est pas récupéré): 

export class Service {
  result: string;

  constructor(private route: ActivatedRoute) {
    this.getData();
  }

  getData() {
    this.route.params.subscribe(params => {
      this.result = params['test'];
    });
  }
}
20
Steve Van Opstal

Service Voici un singleton qui appartient à l'injecteur de racine et qui est injecté avec root ActivatedRoute instance .

Les points de vente ont leur propre injecteur et propre instance ActivatedRoute .

La solution ici est de laisser les composants de route avoir leurs propres instances Service:

@Component({
  ...
  providers: [Service]
})
export class MainComponent { ... }
16
estus

La answer of estus fournit une bonne solution lorsque plusieurs instances de service ne posent pas de problème.

La solution suivante obtient directement un paramètre du routeur et permet au service d’avoir une instance:

export class Service {
  result: string;

  constructor(private router: Router) {
    this.result = router.routerState.snapshot.root.children[0].url[index].path
  }
}

ou comme observable:

export class Service {
  result: string;

  constructor(private router: Router) {
    this.router.routerState.root.children[0].url.map((url) => {
      this.result = url[index].path;
    });
  }
}

sinon, lorsque routerState n'est pas disponible:

export class Service {
  result: string;

  constructor(private router: Router) {
    this.router.parseUrl(this.router.url).root.children.primary.segments[index].toString();
  }
}

Index est la position du param dans l'URL.

7
Steve Van Opstal

Je ne vois pas de directive routerLink dans votre code Plunker que vous avez fourni.

Vous devez utiliser une directive routerLink pour accéder à votre composant, où vous fournissez le paramètre, à vous seul pour pouvoir le récupérer. Par exemple:

<a routerLink="/myparam" >Click here to go to main component</a>
0
siva636

Je suis tombé sur ce problème et la solution de travail que je termine est la suivante.

@Component({
  selector: 'app-sample',
  styleUrls: [`../sample.component.scss`],
  templateUrl: './sample.component.html',
})
export class AppSampleComponent {
  constructor(private route: ActivatedRoute,
              private someService: SomeService){}
  public callServiceAndProcessRoute(): void {
    this.someService.processRoute(route);
  }
}

@Injectable()
export class SomeService {
  public processRoute(route: ActivatedRoute): void {
  // do stuff with route
  }
}

Donc, vous passerez la ActivatedRoute au service en tant que param.

0
T04435