我有一个非常奇怪的问题: 的index.html
<navigation-menu *ngIf="isLoggedIn"></navigation-menu>
<div class="content-wrapper" [ngClass]="{'fullContent' : !isLoggedIn}">
<section class="content">
<router-outlet></router-outlet>
</section>
</div>
导航菜单是导航菜单的组件。 在路由器插座内容中有一个名为&#34; assets&#34;的组件。
我在资产组件中做了什么:
import { ActivatedRoute}from "@angular/router";
constructor(private route: ActivatedRoute){}
public ngOnInit(): void {
this.route.params.subscribe(params => {
const id = params["id"];
}
这有效,我得到了我的路线参数(有点&#34; asset /:id)。
现在我在导航菜单组件(在#34;外部&#34;路由器插座)和名为contextservice的全局服务中尝试了相同的操作。 与上面的代码相同,但在路由更改时甚至没有触发。如果我尝试获取当前路由器快照
const strId = this.route.snapshot.params["id"];
触发NavigationEnd事件后,结果相同:strId未定义,因为params是一个空对象。
它仅适用于我的资产组件。 这是按预期工作还是应该如何处理?
我的意图是从全局服务(或者像导航菜单这样的&#34;全局&#34;组件)触发事件,该事件正在监听所有路径(-params)更改。
我唯一的解决方案是在每个NavigationEnd事件之后解析完整的URL,在我看来这是不正确的方法......或者处理每个子组件(在路由器插座中)的params更改。
也许我在理解中只有一个基本错误......
由于
接受答案的解决方案:
this.router.events.subscribe(val => {
if (val instanceof RoutesRecognized) {
var strId = val.state.root.firstChild.params["id"];
}});
不要忘记从角度路由器导入RoutesRecognized !!
答案 0 :(得分:19)
路由器添加的组件获取路由器段(ActivatedRoute
),但在服务中没有激活路由。您可以订阅router.events并遍历路由树(router.firstChild ...`)以获取您需要的特定路由分段的参数。
答案 1 :(得分:1)
这是一个有角度的服务:
import {Injectable} from '@angular/core';
import {ActivatedRoute, NavigationEnd, NavigationExtras, ParamMap, Router} from "@angular/router";
import {RouterExtensions} from "nativescript-angular/router";
import {NavigationOptions} from "nativescript-angular/router/ns-location-strategy";
import {Observable} from "rxjs/Observable";
import {first} from "rxjs/operators/first";
import {filter} from "rxjs/operators/filter";
import {map} from "rxjs/operators/map";
import {switchMap} from "rxjs/operators/switchMap";
import {unRegisterAndroidOnBack} from "../../utils/view.utils";
@Injectable()
export class RoutingService
{
constructor(private routerExtensions: RouterExtensions, private route: ActivatedRoute, private router: Router)
{
}
public getActivatedRouteParameter(paramName: string): Observable<ParamMap>
{
return this.router.events.pipe(filter(e => e instanceof NavigationEnd),
map((): ActivatedRoute =>
{
let route = this.route;
while (route.firstChild)
{
route = route.firstChild;
}
return route;
}),
filter((route: ActivatedRoute) => route.outlet === 'primary'),
switchMap((route: ActivatedRoute) => route.paramMap) , first());
}
答案 2 :(得分:1)
实际上,您的activatedRoute是正确的并且已更新,但是您拥有其中的所有树。因此,如果您一路走到route.firstChild内部,您将最终找到最后一条路线,我将其称为deeperActivatedRoute(在route.firstChild ... route.firstChild内部)
所以我要做的是创建一个服务来跟踪deeperRoute,并使其始终可访问
import { Injectable } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
@Injectable()
export class ActivatedRouteService {
private _deeperActivatedRoute: ActivatedRoute;
get deeperActivatedRoute(): ActivatedRoute {
return this._deeperActivatedRoute;
}
constructor(private router: Router, private route: ActivatedRoute) {}
init(): void {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
// Traverse the active route tree
let activatedChild = this.route.firstChild;
if (activatedChild != null) {
let nextActivatedChild;
while (nextActivatedChild != null) {
nextActivatedChild = activatedChild.firstChild;
if (nextActivatedChild != null) {
activatedChild = activatedChild.firstChild;
}
}
}
this._deeperActivatedRoute = activatedChild || this.route;
}
});
}
}
然后在app.component.ts中启动服务(只是为了确保它始终处于跟踪状态)
export class AppComponent {
constructor(private activatedRouteService: ActivatedRouteService) {
this.activatedRouteService.init();
}
}
最后,无论您身在何处,都要走自己的路线:
export class ForbiddenInterceptor implements HttpInterceptor {
constructor(private activatedRouteService: ActivatedRouteService) { }
doYourStuff(): void {
//you'll have the correct activatedRoute here
this.activatedRouteService.deeperActivatedRoute;
}
}
回答问题,您只需采取deeperActivatedRoute并正常检查snapshop.url,就像在组件中一样
答案 3 :(得分:1)
我一直在浏览一个简单的网络解决方案,终于找到了可以在angular 8中工作的东西。
https://medium.com/@eng.ohadb/how-to-get-route-path-parameters-in-an-angular-service-1965afe1470e
这按预期工作。网上有许多不同的口味。但是,只有这个为我工作。我是rxjs和观察者管道系统的新手,所以当链对我来说很长时,它很快就会造成混乱。
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!!!!
});
}
}
显然,之后,您可以根据需要设计服务。连接参数。