Angular 2 활성화된 경로 매개 변수가 서비스 내 또는 외부에서 작동하지 않음
매우 이상한 문제가 있습니다: index.html
<navigation-menu *ngIf="isLoggedIn"></navigation-menu>
<div class="content-wrapper" [ngClass]="{'fullContent' : !isLoggedIn}">
<section class="content">
<router-outlet></router-outlet>
</section>
</div>
탐색 메뉴는 탐색 메뉴의 구성 요소입니다.라우터-아웃렛 콘텐츠에는 "자산"이라는 구성 요소가 있습니다.
자산 구성 요소에서 수행한 작업:
import { ActivatedRoute}from "@angular/router";
constructor(private route: ActivatedRoute){}
public ngOnInit(): void {
this.route.params.subscribe(params => {
const id = params["id"];
}
이것은 작동하고 저는 제 경로의 매개 변수("asset/:id")를 얻습니다.
이제 저는 내비게이션 메뉴 구성요소(라우터 콘센트 외부에 있음)와 컨텍스트 서비스라는 글로벌 서비스에서 동일하게 시도했습니다.위의 코드와 동일하지만 경로 변경 시에도 트리거되지 않습니다.현재 라우터 스냅샷을 가져오려고 하는 경우
const strId = this.route.snapshot.params["id"];
NavigationEnd 이벤트가 트리거된 후 동일한 결과가 됩니다. 매개 변수가 빈 개체이기 때문에 strId가 정의되지 않았습니다.
내 자산 구성요소에서만 작동합니다.의도한 대로 작동합니까? 아니면 어떻게 처리해야 합니까?
제 의도는 모든 경로(-params) 변경을 수신하는 글로벌 서비스(또는 탐색 메뉴와 같은 "글로벌" 구성 요소)에서 이벤트를 트리거하는 것이었습니다.
제 유일한 해결책은 NavigationEnd 이벤트가 발생할 때마다 전체 URL을 구문 분석하는 것입니다. 제 생각에는 적절한 방법이 아닌 것 같습니다.또는 각 하위 구성요소(라우터 콘센트) 자체의 매개변수 변경을 처리합니다.
아마 제가 이해하는 데에 기본적인 오류가 있는 것 같습니다.
감사해요.
수락된 답변의 솔루션:
this.router.events.subscribe(val => {
if (val instanceof RoutesRecognized) {
var strId = val.state.root.firstChild.params["id"];
}});
각 라우터에서 인식되는 경로를 가져오는 것을 잊지 마십시오!!
라우터에 의해 추가된 구성요소는 라우터 세그먼트를 가져옵니다.ActivatedRoute
통과했지만 서비스에 활성화된 경로가 없습니다.router.events에 가입하고 경로 트리(라우터)를 통과할 수 있습니다.첫째 아이...') 필요한 특정 경로 시퀀스에서 매개 변수를 제거합니다.
https://github.com/angular/angular/issues/11023 도 참조하십시오.
다음은 이를 수행하는 각도 서비스입니다.
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());
}
저는 웹에서 간단한 해결책을 찾아다녔고 마침내 각도 8에서 작동하는 것을 발견했습니다.
https://medium.com/ @eng.ohadb/how-get-route-path-parameters-in-an-vlan-service-httpafe1470e
이것은 예상대로 작동합니다.웹을 통해 사용할 수 있는 다양한 맛이 있습니다.하지만 저에게는 이것 하나만 효과가 있었습니다.저는 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!!!!
});
}
}
분명히 나중에는 원하는 대로 서비스를 설계할 수 있습니다.매개 변수를 연결합니다.
사실, 당신의 활성화된 경로는 정확하고 업데이트되었지만, 당신은 그 안에 모든 트리를 가지고 있습니다. 그래서 당신이 경로 안쪽까지 간다면.firstChild, 당신은 마침내 내가 더 깊은 활성화된 경로라고 불렀던 마지막 경로를 찾을 수 있을 것입니다.첫째 아이...route.firstChild)
그래서 제가 한 일은 더 깊은 경로를 추적하고 항상 액세스할 수 있는 서비스를 만드는 것이었습니다.
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;
}
}
질문에 대답하면 구성 요소에서 수행하는 것처럼 더 깊은 활성화된 경로를 사용하여 일반적으로 snapshop.url을 확인할 수 있습니다.
언급URL : https://stackoverflow.com/questions/40375888/angular-2-activatedroute-params-not-working-in-service-or-outside-router-outlet
'programing' 카테고리의 다른 글
eplus를 통해 excel 공식을 호출합니다. (0) | 2023.06.15 |
---|---|
셀의 숫자를 사용하여 셀 참조 생성 (0) | 2023.06.15 |
파이썬에서 프로그램 실행 시간을 어떻게 계산합니까? (0) | 2023.06.15 |
이클립스/CDT로 사용자 지정 파일 만들기 사용 (0) | 2023.06.15 |
MariaDB: [.character.]이(가) 있는 REGEX가 더 이상 작동하지 않습니다('POSIX 비교 요소는 지원되지 않음). (0) | 2023.06.15 |