如何从不是路由器插座的组件获取 angular 10+ 中的 URL 参数?

How to get URL parameter in angular 10+ from a component that's not a router-outlet?

我正在尝试在访问 localhost:4200/?loc=en_LSM_US 时获取名为 'loc' 的 URL GET 参数。该方法的逻辑是,如果没有将loc参数发送到实际页面,那么将计算语言环境。

我正在尝试使用 this.route.snapshot.queryParamMap.get('loc'); 获取参数,但由于实际组件不是路由器出口,因此路由为空。

appComponent 看起来像这样:

<body>
  <app-header></app-header>
  <router-outlet></router-outlet>
  <app-footer></app-footer>
</body>

这是<app-footer>的代码:

private loc: string[] = [];

constructor(
  private route: ActivatedRoute,
  private http: HttpClient
) { }

async ngOnInit() {
  await this.getLoc();
}

private async getLoc() {
  var country: string | any;
  var locStr: string | null = await this.route.snapshot.queryParamMap.get('loc');

  if (locStr == null || locStr == '' ) { // There's no loc in URL
    console.log(locStr);
    if (navigator.language.includes('-')) { // navigator.language ~ 'es-MX'
      var locale: string[] = navigator.language.split('-')
      this.loc = [locale[0], '', locale[1]]
    } else { // navigator.language ~ 'es'
      country = await this.http.get("https://api.ipgeolocationapi.com/geolocate/")
      .pipe(map((json: any): 
        Object => {
          return (json['alpha2'] as string)
        })).toPromise();
      this.loc = [navigator.language, '', country]
    }
  } else { // There's loc in URL
    this.loc = locStr.split('_')
  }
  console.log(this.loc)
}

第一个 console.log(locStr) 输出 null,最后一个 console.log(this.loc) 使用 API 或 navigator.language 输出我的语言环境,尽管 URL 具有不同的语言环境参数 localhost:4200/?loc=en_LSM_US.

async 和 await 将与 promises 一起使用。你的 http.get returns 一个 observable

既然你想使用 awaitasync 你应该切换到 promises 而不是订阅 observable

因此您的代码将是

private async getLoc() {
    var country: string | any;
    var locStr: string | null = await this.route.snapshot.queryParamMap.get('loc');

    if (locStr == null || locStr == '' ) { // There's no loc in URL
      console.log(locStr);
      if (navigator.language.includes('-')) { // navigator.language ~ 'es-MX'
        var locale: string[] = navigator.language.split('-')
        this.loc = [locale[0], '', locale[1]]
      } else { // navigator.language ~ 'es'



 country = await this.http.get("https://api.ipgeolocationapi.com/geolocate/")
        .pipe(map((json: any): 
            Object => {
              return (json['alpha2'] as string)
            })).toPromise();
        this.loc = [navigator.language, '', country]
      }


 }
    } else { // There's loc in URL
      this.loc = locStr.split('_')
    }
    console.log(this.loc)
}

您正试图等待一个可观察对象。那是行不通的。 更好地使用 RXJS:

private getLoc(): Observable<Array<string>> {
    return this.route.queryParamMap.pipe(
        switchMap(({ loc }) => {
            if (loc) {
                return of(locStr.split('-'))
            } else {
                const lang = navigator.language;
                const isLangIncludeDash = lang.includes('-');

                if (isLangIncludeDash) {
                    const langArr = lang.split('');
                    return of([langArr[0], '', langArr[1]]);
                } else {
                    const api$ = this.http.get("https://api.ipgeolocationapi.com/geolocate/");
                    return api$.pipe(map(({ alpha2 }) => [lang, '', alpha2]));
                }
            }
        })
    );
}

然后在任何地方订阅(并在销毁时取消订阅)

ngOnInit() {
  this.getLoc().subscribe(result => this.loc = result);
}

使用Location from @angular/common,你可以使用Location.path()获取当前路径。

并且使用 @angular/common/http 中的 HttpParams,您可以使用 new HttpParams({ fromString: "string" }).

从字符串中解析 http 参数

所以,做:

constructor(
  private Location:Location
) { }

ngOnInit() {
  console.log(new HttpParams({ fromString: this.Location.path()}))
}

应该在您的网络控制台中打印如下内容:/current?param=value&etc=0,其中 /current 是您的实际路线,任何参数都在 ? 之后。因此,只需对字符串进行清理,消除从 0 到 ? 的字符,然后将字符串传递给 HttpParams 即可。