【问题标题】:Parent components gets empty Params from ActivatedRoute父组件从 ActivatedRoute 获取空参数
【发布时间】:2017-08-14 07:13:06
【问题描述】:

我有一个主要组件,其中有一个路由器插座。在路由器插座中加载的组件中,我获取 url 参数,如下所示:

ngOnInit(): void {
    // _route is injected ActivatedRoute
    this._route.params.subscribe((params: Params) => {
        if(params['url']){
          this.testUrl = params['url'].replace(new RegExp('\%2[fF]', 'g'), '/');

        }

    });
}

这很好用,但是当我在顶级组件上尝试它时,params 对象始终为空。我不明白为什么嵌套组件参数对象中有数据,我试图以完全相同的方式访问它。没有错误可以继续,param 对象只是空的。

为什么我的父组件没有从ActivatedRoute获取正确的Params对象?

编辑:

作为请求的完整父组件

import { OnInit, Component, Directive } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
})
export class AppComponent {
  public testUrl: string;
  constructor(private router: Router, private _route: ActivatedRoute) {

  }
  ngOnInit(): void{
    this._route.queryParams.subscribe((params: Params) => {
      console.log(params);

      if (params['url']) {
        this.testUrl = params['url'].replace(new RegExp('\%2[fF]', 'g'), '/');
        alert(params['url']);
      }
    });
  }

}

app.module.ts 的路由器代码:

RouterModule.forRoot([
  { path: '', component: CheckMobileComponent },
  { path: '**', component: CheckMobileComponent }
]),

嵌套模块的路由器代码:

RouterModule.forChild([
 { path: 'report', component: MobileReportComponent }

我的 app.component 没有直接指定的路由,因为它是由 index.html 中的选择器加载的。

【问题讨论】:

  • 分享你的父组件代码
  • @Sid 更新问题
  • 请也添加您的路线代码
  • @Sid 再次更新
  • 存在(我认为仍然)延迟加载组件的一些问题,以及观察.params.data 变化的能力。如果遇到这种情况,您可能需要观察 NavigationEnd 事件,然后访问 activatedRoute.snapshot

标签: angular typescript


【解决方案1】:

ActivatedRoute 适用于通过router-outlet 加载的组件。 From docs - 它:

包含有关与在插座中加载的组件关联的路由的信息。

我认为您不能在未加载到插座中的组件中使用它。它也不适用于您的组件扩展的基类。

class A { constructor(public route: ActivatedRoute) } 
class B extends A { ngOnInit() { this.route; } }        // not working
class C { constructor(public route: ActivatedRoute) }   // working if loaded in outlet

【讨论】:

  • 感谢您的回复。我想我必须做一个中介服务?还是有更简单的方法?
  • 想不出任何自动取款机。我通常将其留在组件中,但取决于您使用它的频率/频率,服务可能是个好主意...
【解决方案2】:

ActivatedRoute:包含有关路由的信息,该路由与加载在路由器插座中的组件相关联。如果您想访问它之外的路线详细信息,请使用下面的代码。

import { Component } from '@angular/core';
import { Router, ActivatedRoute, Params, RoutesRecognized } from '@angular/router';

export class AppComponent {

    constructor(private route: ActivatedRoute, private router: Router) {

    }

    ngOnInit(): void {
        this.router.events.subscribe(val => {

            if (val instanceof RoutesRecognized) {

                console.log(val.state.root.firstChild.params);

            }
        });

    }
}

还有其他方法可以在组件之间共享数据,例如by using a service

有关如何将其作为概念处理的更多详细信息,read comments here

【讨论】:

  • 这是一个很好的信息,这是我看到的关于这种行为的任何信息,感谢分享:)
  • this.route.events 未定义。也许自 2017 年以来发生了一些变化?
  • @RobKohr 是的,也许从那时起有些变化,早在 2017 年,我在发布答案之前测试了这段代码。不幸的是,我不记得我当时使用的版本。
  • 示例适用于 Angular 11,刚刚测试过。
【解决方案3】:

非常简单的答案

import { Component } from '@angular/core';
import { Router, ActivatedRoute, Params, RoutesRecognized } from '@angular/router';

export class AppComponent {

    constructor(private actRoute: ActivatedRoute, private router: Router){}

    ngOnInit(): void {
        this.actRoute.firstChild.params.subscribe(
            (params: any) => {
                if (params.hasOwnProperty('<whatever the param name>') != '') {
                    //do whatever you want
                    console.log(params.<whatever the param name>);
                } 
            });
    }
}

【讨论】:

  • 哇,太棒了!最好的解决方案。不敢相信我必须处理像这样过于复杂的事情:medium.com/@tomastrajan/…
  • @hugoderhungrige 因为如果您不在根路由器的子组件中,这将不起作用。我目前正在处理一个项目,该项目没有在根路由中包含标题菜单,并且退休任何参数真的很痛苦。呃。
  • 你能解释一下为什么这个解决方案是解决方案吗?作为 Angular 的初学者,不太了解这与仅使用 'actRoute.params.subscribe' 之间的区别。谢谢
【解决方案4】:

我遇到了一个非常相似的问题,主要是因为我对路线的实际运作方式有误解。我以为我可以沿着路径参数链向上走,每个参数都是父/子关系。但是,如果一个路由有多个路径元素(例如/dashboardprofile/:user_id),这将取决于您如何在路由模块中设置路由。

解释一个让我点击的不同方式:

// If I am trying to access ActivatedRoute from the CheckMobileComponent (say 
// through a `router-outlet`), I could get it through something like 
// `this._route.firstChild`

{ path: '', component: CheckMobileComponent, children: [

    // If I want to get things from the '' context in MobileReportComponent, it 
    // would be through something like `this._route.parent`

    { path: 'report', component: MobileReportComponent }

  ]   

}

【讨论】:

    【解决方案5】:

    如果您想通过服务访问路由器参数,这种方法是行不通的!考虑使用服务来防止“路由参数值提取逻辑”的复制(来自此Medium article):

    @Injectable({
      providedIn: 'root'
    })
    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!!!!
          });
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-08-26
      • 2021-03-16
      • 1970-01-01
      • 1970-01-01
      • 2017-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-14
      相关资源
      最近更新 更多