programing

Angular 2 활성화된 경로 매개 변수가 서비스 내 또는 외부에서 작동하지 않음

magicmemo 2023. 6. 15. 21:46
반응형

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

반응형