簡體   English   中英

Angular queryParamMap 為空,然后填充

[英]Angular queryParamMap is empty, then populated

我在我的應用程序中創建了一個新模塊,這樣我就可以分離不需要通信的部分,並創建了一個 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 ;我只想要來自的查詢參數我的 url

謝謝你的幫助

我將提供2個解決此問題的方法,首先,使用skip運算符:

由於Activated Route是一個BehaviorSubject,所以首先我們得到一個空值,然后是實際的查詢參數,這樣我們就可以跳過第一個值:

(注意,這個解決方案使用lettable運算符,因此使用pipe() ,如果你沒有使用lettable運算符,你可以像對待任何其他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)}

第二種解決方案,使用常規的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, " "));
}

我將指出這個原始代碼的stackoverflow答案

當沒有查詢參數並且我們需要檢測它時,@Lakston 接受的答案沒有考慮流程。 經過一番努力后,我為我們這些使用 SSR(服務器端渲染,意味着我們沒有可用的瀏覽器全局對象)並且需要檢測無查詢參數場景的人找到了一個真正的解決方案。

import { Location } from '@angular/common';
----------------------------------------------------------
constructor(private location: Location)
----------------------------------------------------------
let questionIndex = this.location.path().indexOf('?');
questionIndex = questionIndex === -1 ? Infinity : questionIndex;
const queryParams = (<any>Object).fromEntries(this.location.path().substr(questionIndex + 1).split('&').filter(str => str).map(el => el.split('=')));

所有積分歸功於 YugasVasyl,他將此答案發布在: https://github.com/angular/angular/issues/12157

我已經在我的項目中測試過它並且它有效。 祝福...

我認為問題是您使用ExportsComponent進行引導:

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

您在此處指定的組件在應用程序啟動時使用,因此它的早期調用ngOnInit

你可以做的是有一個單獨的組件用於bootstrapping和單獨的ExportComponent ,這是一個例子(參見實時版本 ):

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);

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

組件.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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM