无法从 App.Component 读取查询字符串参数

And*_*NET 5 typescript angular-routing angular angular-router angular-router-params

我想在整个应用程序中集中读取特定查询字符串参数的位置/方式,因此我认为最好的位置是在 app.component.ts 中

export class AppComponent implements OnInit, OnDestroy {
  constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute) {
  }
Run Code Online (Sandbox Code Playgroud)

然后,在ngOnInit(),我查看快照以及不同的订阅:

  ngOnInit(): void {
    console.log('AppComponent - ngOnInit() -- Snapshot Params: ' + this.activatedRoute.snapshot.params['code']);
    console.log('AppComponent - ngOnInit() -- Snapshot Query Params: ' + this.activatedRoute.snapshot.queryParams['code']);
    console.log('AppComponent - ngOnInit() -- Snapshot Query ParamMap: ' + this.activatedRoute.snapshot.queryParamMap.get('code'));

    this.activatedRouteParamsSubscription = this.activatedRoute.params.subscribe(params => {
      console.log('AppComponent - ngOnInit() -- Subscription Params: ' + params['code']);
    });

    this.activatedRouteQueryParamsSubscription = this.activatedRoute.queryParams.subscribe(params => {
      console.log('AppComponent - ngOnInit() -- Subscription Query Params: ' + params['code']);
    });

    this.activatedRoute.queryParamMap.subscribe(queryParams  => {
      console.log('AppComponent - ngOnInit() -- Subscription Query ParamMap: ' + queryParams.get('code'));
    });

    this.routerEventsSubscription = this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        console.log('AppComponent - ngOnInit() -- Subscription NavigationEnd: URL=', event.url);
      }
    });
  }
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我已经设置了一个订阅paramsqueryParamsqueryParamMaprouter.events

在页面导航之间触发的唯一一个是router.events,但在那里,我必须手动解析 URL 以获取查询字符串。

不确定这是否对其有任何影响,但我正在覆盖路由重用策略,因此即使页面在同一条路由上也会重新加载:

export class AppRoutingModule {
  constructor(private router: Router) {
    this.router.routeReuseStrategy.shouldReuseRoute = function() {
        return false;
    };
  }
}
Run Code Online (Sandbox Code Playgroud)

第一次访问时根页面的输出:

AppComponent - constructor() -- Snapshot Params: undefined
AppComponent - constructor() -- Snapshot Query Params: undefined
AppComponent - ngOnInit() -- Snapshot Params: undefined
AppComponent - ngOnInit() -- Snapshot Query Params: undefined
AppComponent - ngOnInit() -- Snapshot Query ParamMap: null
AppComponent - ngOnInit() -- Subscription Params: undefined
AppComponent - ngOnInit() -- Subscription Query Params: undefined
AppComponent - ngOnInit() -- Subscription Query ParamMap: null
AppComponent - ngOnInit() -- Subscription NavigationEnd: URL= /?code=logged-out
Run Code Online (Sandbox Code Playgroud)

解决方案

正如@Thomaz 和@Nathan 所指出的,我的问题是 App.Component 不在router-outlet.

此外,@Nathan 还指出:

您可以访问路由器事件并在应用程序中的任何位置迭代它们,这就是您的 router.events.subscribe(...) 触发的原因。

然后我在我的路线上启用了跟踪:

RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload', enableTracing: true })
Run Code Online (Sandbox Code Playgroud)

并看到该ActivationEnd事件包含具有snapshotqueryParams 的 a 。最后,我订阅路由器事件并处理我的查询字符串值(如果事件是ActivationEnd.

this.router.events.subscribe(event => {
      if(event instanceof ActivationEnd) {
        const code = event.snapshot.queryParams['code'];
        if (code) {
          // handle it...
        }
      }
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*eck 7

ActivatedRoute可以从通过router-outlet. 由于AppComponent未通过任何插座加载,因此您无法订阅其中的ActivatedRoute参数。重用策略对此没有影响。

从文档https://angular.io/api/router/ActivatedRoute我们知道以下内容:

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

没有出口加载AppComponent,因此您的订阅不会触发。您可以访问路由器事件并在应用程序中的任何位置迭代它们,这就是router.events.subscribe(...)触发器的原因。