角queryParamMap为空,然后填充

Lak*_*ton 5 angular2-routing angular

我在应用程序中创建了一个新模块,因此我可以将不需要通信的部分分开,并使用其自己的路由模块和组件创建了一个new.module.ts:

new-routing.module.ts

const exportRoutes: Routes = [
  {
    path: 'export',
    component: ExportsComponent
  }
]

@NgModule({
  imports: [RouterModule.forRoot(exportRoutes)],
  exports: [RouterModule]
})
export class ExportRoutingModule {}
Run Code Online (Sandbox Code Playgroud)

new.module.ts

import { Router } from '@angular/router'
import { BrowserModule } from '@angular/platform-browser'

// Routing Module
import { NewRoutingModule } from './new-routing.module'

@NgModule({
  imports: [..., ExportRoutingModule, ...],
  declarations: [ExportsComponent],
  bootstrap: [ExportsComponent]
})
Run Code Online (Sandbox Code Playgroud)

我有一个简单的index.html

<body class="app">
  <router-outlet></router-outlet> // outlet is here because I read that I needed it to be able to use activated route, I actually just want the query params
</body>
Run Code Online (Sandbox Code Playgroud)

最后,问题出在哪里,我的组件:

export class MyComponent implements OnInit {

constructor(private activatedRoute: ActivatedRoute) {}

ngOnInit() {this.activatedRoute.queryParamMap.subscribe(
(params: ParamMap) => console.log(params) 
// Do stuff with params => error)}
Run Code Online (Sandbox Code Playgroud)

当我http://localhost:4200/export?firstParam=1.00,2.00,3.00在控制台中导航到时,它们params被登录两次,一次为空,一次被填充为:

ParamsAsMap {params: {…}}
keys:(...) // empty
params:{} // empty

core.js:3565 Angular is running in the development mode. Call enableProdMode() to enable the production mode.

ParamsAsMap {params: {…}}
keys:Array(3)
params:{firstParam: "1.00,2.00,3.00", secondParam: "bla"}
Run Code Online (Sandbox Code Playgroud)

这导致我的组件抛出错误,因为我需要这些参数来显示我的组件,并且第一次登录它们时它们是空的,因此:

  • 他们为什么两次被讨价还价?
  • 为什么在可观察到的参数具有值之前执行我的代码?
  • 我能摆脱路由器出口吗(因为我没有涉及该模块的路由,所以我实际上并不需要它,我只是用了它,因为我读到activatedRoute没有它就无法使用;我只是想从我的查询参数网址

谢谢你的帮助

Lak*_*ton 5

我将为这个问题提供两种解决方案,首先使用skip运算符:

由于激活的路由是一个BehaviorSubject,所以首先我们将得到一个空值,然后是实际的查询参数,这样我们就可以跳过第一个值:

(注意,这个解决方案使用可出租运算符,因此pipe(),如果您不使用可出租运算符,您可以像任何其他 rxjs 运算符一样链接它:.skip(1)

export class MyComponent implements OnInit {

  constructor(private activatedRoute: ActivatedRoute) {}

  ngOnInit() 
    {this.activatedRoute.queryParamMap.pipe(skip(1)).subscribe(
    (params: ParamMap) => console.log(params)}
Run Code Online (Sandbox Code Playgroud)

第二种解决方案,使用常规 javascript 函数来检索 params :

ngOnInit() {
  const token = this.getParameterByName('access_token');
  console.log(token);
}

getParameterByName(name: any) {
  let url = window.location.href;
  name = name.replace(/[[]]/g, "\$&");
  var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
  results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/+/g, " "));
}
Run Code Online (Sandbox Code Playgroud)

我会向您指出原始代码的stackoverflow 答案