Angular 2.0.2: ActivatedRoute пуст в службе

Я хочу использовать ActivatedRoute для получения параметров маршрута в сервисе, как в компоненте. Однако, когда я внедряю объект ActivatedRoute в Сервис, он содержит пустую переменную params

Я создал плункер, который воспроизводит поведение: http://plnkr.co/edit/sckmDYnpIlZUbqqB3gli

Обратите внимание, что целью является использование параметра в сервисе, а не в компоненте, способ установки плунжера предназначен исключительно для демонстрации проблемы.

Компонент (test получен):

export class Component implements OnInit {
  result: string;

  constructor(private route: ActivatedRoute) {
  }

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

Сервис (test не получен):

export class Service {
  result: string;

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

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

Ответ 1

Service Ниже приведен синглтон, который принадлежит инжектору корня и вводится root ActivatedRoute экземпляр.

Выходы получают собственный инжектор и собственный экземпляр ActivatedRoute.

Решение здесь заключается в том, чтобы позволить компонентам маршрута иметь свои экземпляры Service:

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

Ответ 2

Ответ estus обеспечивает хорошее решение, когда несколько экземпляров службы не являются проблемой.

Следующее решение получает параметр прямо от маршрутизатора и позволяет службе иметь один экземпляр:

export class Service {
  result: string;

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

или как наблюдаемое:

export class Service {
  result: string;

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

альтернативно, когда маршрутизаторState недоступен:

export class Service {
  result: string;

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

Индекс - это положение парама в URL.

Ответ 3

Я не вижу директивы routerLink в вашем указанном вами коде Plunker.

Вам нужно использовать директиву routerLink для перехода к вашему компоненту, где вы предоставите параметр, и только вы можете его получить. Например:

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

Ответ 4

Я столкнулся с этой проблемой, и рабочее решение, которым я заканчиваю, заключается в следующем.

@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
  }
}

Таким образом, вы передадите ActivatedRoute сервису в качестве параметра.