Angular queryParamMap为空,然后填充

时间:2017-11-22 09:14:16

标签: angular angular2-routing

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

new-routing.module.ts

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

@NgModule({
  imports: [RouterModule.forRoot(exportRoutes)],
  exports: [RouterModule]
})
export class ExportRoutingModule {}

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]
})

我有一个简单的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>

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

export class MyComponent implements OnInit {

constructor(private activatedRoute: ActivatedRoute) {}

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

当我在我的控制台中导航到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"}

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

  • 他们为什么要两次记录?
  • 为什么我的代码在我的params observable有值之前执行?
  • 我可以摆脱路由器插座(我不需要这个,因为我没有涉及此模块的路由,我只是使用它,因为我读到没有它我不能使用activatedRoute;我只想从我的网址
  • 查询参数

感谢您的帮助

3 个答案:

答案 0 :(得分:0)

我认为问题在于您使用ExportsComponent进行自举:

@NgModule({
  ...
  bootstrap: [ExportsComponent]
})

此处指定的组件在应用程序启动时使用,因此ngOnInit会提前调用。

您可以做的是为引导创建一个单独的组件并单独ExportComponent,这是一个示例(请参阅the live version):

import { bootstrap } from '@angular/platform-browser-dynamic';
import { RouterModule, Router, Routes, ActivatedRoute } from '@angular/router';
import { NgModule, Component, OnInit }       from '@angular/core';
import { BrowserModule }  from '@angular/platform-browser';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

@Component({
    selector: 'my-app',
    template: `
    <nav class="rbe-plunk-nav">
      <ul>
        <li> <a [routerLink]="['/']">Homepage</a> </li>
        <li> <a [routerLink]="['/about']">Export</a> </li>
      </ul>
    </nav>

    <main>
      <router-outlet></router-outlet>
      <!-- The router will put the content here, right after the outlet -->
    </main>
  `
})
export class AppComponent { }

@Component({
  selector: 'home',
  template: '<h1>Home: </h1>'
})
export class HomeComponent { }

@Component({
  selector: 'export',
  template: '<h1>Export: </h1>'
})
export class ExportComponent implements OnInit {

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
     this.route.queryParamMap.subscribe(paramMap => {
         console.log("Export: ");
         console.log(paramMap);
     });
  }
}

export const routes: Routes = [
  { path: '',         component: HomeComponent },
  { path: 'about',    component: ExportComponent }
];

@NgModule({
  imports: [
    BrowserModule,
    RouterModule.forRoot(
      routes,
      { /*enableTracing: true*/ }
    )
  ],
  declarations: [
    AppComponent,
    HomeComponent,
    ExportComponent
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule {
  // Diagnostic only: inspect router configuration
  constructor(router: Router) {
    console.log('Routes: ', JSON.stringify(router.config, undefined, 2));
  }
}

platformBrowserDynamic().bootstrapModule(AppModule);

答案 1 :(得分:0)

我将首先使用skip运算符

为此问题提供2种解决方案

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

(注意,此解决方案使用lettable运算符,因此使用pipe(),如果您不使用lettable运算符,您可以像处理任何其他rxjs运算符一样链接它:.skip(1) < / em>的

export class MyComponent implements OnInit {

  constructor(private activatedRoute: ActivatedRoute) {}

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

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

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, " "));
}

我会指出原始代码的这个stackoverflow answer

答案 2 :(得分:0)

网址:http://localhost:4200/licenca-filtro?param=60&param2=50

component.ts

constructor(
    private route: ActivatedRoute,
  ) {

    const param1 = this.route.queryParams['value']['param'];
    const param2 = this.route.queryParams['value']['param2'];
    
    console.log(param1, param2);

   }

输出:60 50