Angular 2: Как я могу получить параметры маршрута снаружи маршрутизатора-розетки
Подобный вопрос к Angular2 Получить параметры маршрутизатора за пределами маршрутизатора-розетки, но нацеливаясь на выпускную версию Angular 2 (то есть версию 3.0.0 маршрутизатора). У меня есть приложение со списком контактов и выходом маршрутизатора для отображения или редактирования выбранного контакта. Я хочу убедиться, что в любой точке выбран правильный контакт (в том числе при загрузке страницы), поэтому я хотел бы иметь возможность читать параметр "id" из маршрута при каждом изменении маршрута.
Я могу заполучить маршрутизацию событий, подписавшись на свойство events маршрутизатора, но объект Event просто дает мне доступ к необработанному URL, а не к его разобранной версии. Я могу разобрать это с помощью метода parseUrl маршрутизатора, но формат этого не особенно полезен и будет довольно хрупким, поэтому я бы не стал его использовать. Я также посмотрел все, хотя свойство routerState маршрутизатора в событиях маршрутизации, но params всегда пустой объект в снимке.
Есть ли прямой прямой способ сделать это, что я только что пропустил? Должен ли я обернуть список контактов в розетку маршрутизатора, которая никогда не изменится, чтобы заставить это работать, или что-то в этом роде?
1 ответ
Если кто-то искал последнее решение этой проблемы (angular 8), я наткнулся на эту статью, которая мне очень понравилась.
https://medium.com/@eng.ohadb/how-to-get-route-path-parameters-in-an-angular-service-1965afe1470e
Очевидно, что вы можете сделать ту же реализацию прямо в компоненте вне розетки маршрутизатора, и она все равно должна работать.
export class MyParamsAwareService {
constructor(private router: Router) {
this.router.events
.pipe(
filter(e => (e instanceof ActivationEnd) && (Object.keys(e.snapshot.params).length > 0)),
map(e => e instanceof ActivationEnd ? e.snapshot.params : {})
)
.subscribe(params => {
console.log(params);
// Do whatever you want here!!!!
});
}
В надежде сохранить ту же борьбу, через которую я прошел.
Я боролся с этой проблемой целый день, но, думаю, наконец-то нашел способ, как это сделать, прослушав одно из событий маршрутизатора, в частности. Будьте готовы, это немного сложно (некрасиво?), Но на сегодняшний день это работает, по крайней мере, с последней версией Angular (4.x) и Angular Router (4.x). Этот кусок кода может не работать в будущем, если они что-то изменят.
По сути, я нашел способ получить путь к маршруту, а затем самостоятельно перестроить карту параметров.
Итак, вот оно:
import { Component, OnInit } from '@angular/core';
import { Router, RoutesRecognized } from '@angular/router';
@Component({
selector: 'outside-router-outlet',
templateUrl: './outside-router-outlet.component.html',
styleUrls: ['./outside-router-outlet.component.css']
})
export class OutSideRouterOutletComponent implements OnInit {
path: string;
routeParams: any = {};
constructor(private router: Router) { }
ngOnInit() {
this.router.events.subscribe(routerEvent => {
if (routerEvent instanceof RoutesRecognized) {
this.path = routerEvent.state.root['_routerState']['_root'].children[0].value['_routeConfig'].path;
this.buildRouteParams(routerEvent);
}
});
}
buildRouteParams(routesRecognized: RoutesRecognized) {
let paramsKey = {};
let splittedPath = this.path.split('/');
splittedPath.forEach((value: string, idx: number, arr: Array<string>) => {
// Checking if the chunk is starting with ':', if yes, we suppose it's a parameter
if (value.indexOf(':') === 0) {
// Attributing each parameters at the index where they were found in the path
paramsKey[idx] = value;
}
});
this.routeParams = {};
let splittedUrl = routesRecognized.url.split('/');
/**
* Removing empty chunks from the url,
* because we're splitting the string with '/', and the url starts with a '/')
*/
splittedUrl = splittedUrl.filter(n => n !== "");
for (let idx in paramsKey) {
this.routeParams[paramsKey[idx]] = splittedUrl[idx];
}
// So here you now have an object with your parameters and their values
console.log(this.routeParams);
}
}