Як отримати параметри запиту з URL у Angular 5?


181

Я використовую кутовий 5.0.3, я хотів би почати свою програму з купою параметрів запиту, як /app?param1=hallo&param2=123. Кожна порада, наведена у розділі Як отримати параметри запиту з URL у Angular 2? не працює для мене.

Будь-які ідеї, як змусити працювати параметри запиту?

private getQueryParameter(key: string): string {
  const parameters = new URLSearchParams(window.location.search);
  return parameters.get(key);
}

Ця приватна функція допомагає мені отримати мої параметри, але я не думаю, що це правильний шлях у новому кутовому середовищі.

[оновлення:] Має основний додаток

@Component({...})
export class AppComponent implements OnInit {

  constructor(private route: ActivatedRoute) {}

  ngOnInit(): void {
    // would like to get query parameters here...
    // this.route...
  }
}

Ви використовуєте роутери? Звідки походить URL?
Vinod Bhavnani

Так, майте ActivateRoute. Я оновив своє запитання, щоб показати, як виглядає мій основний компонент.
Ларс

Чи можете ви також показати мені постійний маршрут, де ви налаштували всі маршрути?
Вінод Бхавнані

const appRoutes: Routes = [{path: "one", компонент: PageOneComponent}, {path: "", redirectTo: "/ one", pathMatch: "full"}, {path: "**", redirectTo: "/ один "}]; Постійна мій маршрут. Я хотів би отримати всі параметри в головному додатку, зберігати його в DTO, а потім перейти на іншу сторінку. Навігація по сторінках працює як очікується, але параметри запиту я отримую в основному лише за допомогою функції "getQueryParameter". Я розумію у вашому питанні, що існує щось, що я забув. Чи потрібно мені десь позначати свої імена параметрів?
Ларс

Так, у своїх маршрутах потрібно також визначити параметри. Якщо ви перевірите документи маршрутизації на angular.io, ви зможете побачити, як вони визначають параметри певного маршруту. Щось подібне {path: 'abc /: param1', компонент: компонентClassName}
Vinod Bhavnani

Відповіді:


238

У Angular 5 параметри запиту мають доступ, підписавшись на this.route.queryParams.

Приклад: /app?param1=hallo&param2=123

param1: string;
param2: string;
constructor(private route: ActivatedRoute) {
    console.log('Called Constructor');
    this.route.queryParams.subscribe(params => {
        this.param1 = params['param1'];
        this.param2 = params['param2'];
    });
}

тоді як до змінних контуру можна отримати доступ this.route.snapshot.params

Приклад: /param1/:param1/param2/:param2

param1: string;
param2: string;
constructor(private route: ActivatedRoute) {
    this.param1 = this.route.snapshot.params.param1;
    this.param2 = this.route.snapshot.params.param2;
}

15
Відповідно до Angular 6 dokcs , використання ActivateRoute.queryParams та .params перешкоджає і може бути припинено у наступних версіях; дивіться оновлення тут
grreeenn

1
@ShubhenduVaid поясніть, чому вони повинні використовувати ngOnInit замість конструктора. Найкращою практикою буде використання спостережуваного RxJS, потім використання декларативного підходу при роботі з спостережуваними, а потім використання асинхронізації на html
coderpatomx

118

Це найчистіше рішення для мене

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

export class MyComponent {
  constructor(
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    const firstParam: string = this.route.snapshot.queryParamMap.get('firstParamKey');
    const secondParam: string = this.route.snapshot.queryParamMap.get('secondParamKey');
  }
}

Це корисно, дякую. Щодо кутового 6.0.8, я використовую це, і це працює для мене: this.route.snapshot.queryParams ["firstParamKey"]
fluidguid

2
Це працює для мене в Angular8. this.route.snapshot.queryParamMap працює. this.route.snapshot.paramMap не працює для мене.
Ромео Профійт

89

Я знаю, що ОП попросив рішення Angular 5, але все ж для всіх вас, хто натрапляє на це питання щодо новіших (6+) кутових версій. Посилаючись на Документи , що стосуються ActivateRoute.queryParams (на чому базується більшість інших відповідей):

Два старі властивості ще доступні. Вони менш здатні, ніж їхні замінники, відбиваються та можуть бути застарілими в майбутній кутовій версії.

params - Спостережне, що містить необхідні та необов'язкові параметри, характерні для маршруту. Замість цього використовуйте paramMap.

queryParams - спостережуване, що містить параметри запиту, доступні для всіх маршрутів. Замість цього використовуйте queryParamMap.

За словами Документів , простий спосіб отримати параметри запиту виглядав би так:

constructor(private route: ActivatedRoute) { }

ngOnInit() {
    this.param1 = this.route.snapshot.paramMap.get('param1');
    this.param2 = this.route.snapshot.paramMap.get('param2');
}

Більш просунуті способи (наприклад, повторне використання розширених компонентів) див. У цьому розділі Документів.

Редагувати:

Як правильно сказано в коментарях нижче, ця відповідь є помилковою - принаймні для випадку, визначеного ОП.

OP просить отримати глобальні параметри запиту (/ app? Param1 = hallo & param2 = 123); в цьому випадку ви повинні використовувати queryParamMap (як і у відповіді @ dapperdan1985).

paramMap, з іншого боку, використовується для параметрів, характерних для маршруту (наприклад, / app /: param1 /: param2, в результаті чого / app / hallo / 123).

Дякуємо @JasonRoyle та @daka за те, що вони це вказали.


10
Чи не слід це використовувати для queryParamMapне paramMapотримання параметрів рядка запиту?
Джейсон Ройл

2
@JasonRoyle Здається, ви правильно, paramMapне працює.
daka

1
Цю відповідь потрібно виправити відповідно до вищезазначених коментарів.
дака

@JasonRoyle, дак, ти маєш рацію, дякую, що вказав на це. Виправлено відповідь.
grreeenn

Знайшов ідеальний робочий код: jsonworld.com/blog/…
Soni Kumari

17

Ви також можете використовувати HttpParams , такі як:

  getParamValueQueryString( paramName ) {
    const url = window.location.href;
    let paramValue;
    if (url.includes('?')) {
      const httpParams = new HttpParams({ fromString: url.split('?')[1] });
      paramValue = httpParams.get(paramName);
    }
    return paramValue;
  }

1
Просто уточнюйте, у мене два домени вказують на різний мовний сайт. localhost / -> En, localhost /? lang = fr -> французька. І я маршрутизація: path: '', redirectTo: '/list' . This.route.snapshot для мене не працює, оскільки він перенаправляєТо / список, що усуває 'lang' queryString. Але це рішення працює для мене.
Райан Хуан

Як @RyanHuang, у мене є такий же випуск. Але це рішення спрацювало на моєму першому випробуванні.
Gi1ber7

Знайдіть краще рішення, ніж вище: jsonworld.com/blog/…
Soni Kumari

11
import { ParamMap, Router, ActivatedRoute } from '@angular/router';

constructor(private route: ActivatedRoute) {}

ngOnInit() {
    console.log(this.route.snapshot.queryParamMap);
}

ОНОВЛЕННЯ

import { Router, RouterStateSnapshot } from '@angular/router';

export class LoginComponent {
    constructor(private router: Router) {
        const snapshot: RouterStateSnapshot = router.routerState.snapshot;
        console.log(snapshot);  // <-- hope it helps
    }
}

6
що, здається, недостатньо, я отримую ActivateRouteSnapshot, але queryParams - це порожній об'єкт, парами також порожні, а .queryParamMap.get ('ім'я') повертає нуль. Здається, що ngOnInit () зарано отримувати такі параметри запиту.
Ларс

насправді, якщо ви хочете отримати ці парами, вам слід змінити маршрут.
Дмитро Гринько

У мене кругло близько 10 параметрів у різному порядку. Тому я повинен використовувати названі параметри запиту. І як мені встановити головний AppComponent, щоб зрозуміти, що існує 10 параметрів. url / myprogram? a = 1 & b = 2 & c = 4 ... це виглядає у мене проблема? Чи потрібно мені перенаправляти кожен параметр до іншого компонента? Я сподіваюся, що ні.
Ларс

Ви спробували цей? this.route.snapshot.queryParamMap
Дмитро Грінко

1
@DmitryGrinko введення ідентифікатора об'єкта в маршрут не є поганим зразком, воно дозволяє мати глибоке посилання на детальний вид.
Карл


5

Параметри запиту та шляху (кутова 8)

Для таких URL-адрес, як https://myapp.com/user/666/read?age=23, використовуйте

import { combineLatest } from 'rxjs';
// ...

combineLatest( [this.route.paramMap, this.route.queryParamMap] )
  .subscribe( ([pathParams, queryParams]) => {
    let userId = pathParams.get('userId');    // =666
    let age    = queryParams.get('age');      // =23
    // ...
  })

ОНОВЛЕННЯ

Якщо ви використовуєте this.router.navigate([someUrl]);і ваші параметри запиту вбудовуються в someUrlрядок, то кутовий кодує URL-адресу, і ви отримуєте щось подібне https://myapp.com/user/666/read%3Fage%323 - і вище рішення дасть неправильний результат ( queryParams буде порожнім, і парами шляху можна буде приклеїти до останнього параму шляху, якщо він знаходиться в кінці шляху). У цьому випадку змініть спосіб навігації на цей

this.router.navigateByUrl(someUrl);

1
Дякую @Kamil Kiełczewski, ти врятуєш мій день
Tan Nguyen

4

Наткнувшись на це питання, коли я шукав подібне рішення, але мені не потрібно було нічого, як повне маршрутизація на рівні додатків або більше імпортних модулів.

Наступний код відмінно підходить для мого використання та не потребує додаткових модулів чи імпорту.

  GetParam(name){
    const results = new RegExp('[\\?&]' + name + '=([^&#]*)').exec(window.location.href);
    if(!results){
      return 0;
    }
    return results[1] || 0;
  }

  PrintParams() {
    console.log('param1 = ' + this.GetParam('param1'));
    console.log('param2 = ' + this.GetParam('param2'));
  }

http://localhost:4200/?param1=hello&param2=123 Виходи:

param1 = hello
param2 = 123

2

На жаль, найчистіший розчин не є найбільш розтяжним рішенням. В останніх версіях Angular, в інших відповідях пропонується, що ви можете легко отримати параметри запитів за допомогою ActivateRoute Injectible і спеціально використовуючи або властивість знімка:

this.route.snapshot.queryParamMap.get('param')

або властивість передплати (використовується у випадках, коли рядок запиту оновиться, наприклад, навігація через ідентифікатори користувача):

this.route.queryParamMap.subscribe(params => console.log(params));

Я тут, щоб сказати вам, що ці рішення мають розбіжний недолік, який не було вирішено протягом певного часу: https://github.com/angular/angular/isissue/12157

Загалом, єдине бронепробивне рішення - використовувати старий добрий ванільний javascript. У цьому випадку я створив службу для обробки URL-адрес:

import { Injectable } from '@angular/core';
import { IUrl } from './iurl';

@Injectable()
export class UrlService {
    static parseQuery(url: string): IUrl {
        const query = url.slice(url.indexOf('?')+1).split('&').reduce( (acc,query) => {
            const parts = query.split('=');
            acc[parts[0]] = parts[1];
            return acc;
        }, {});

        return {
            a: query['a'],
            b: query['b'],
            c: query['c'],
            d: query['d'],
            e: query['e']
        }
    }
}

2

Кутовий маршрутизатор забезпечує метод parseUrl (url: string), який аналізує URL-адресу в UrlTree . Однією з властивостей UrlTree є queryParams. Тож ви можете робити що-небудь на кшталт:

this.router.parseUrl(this.router.url).queryParams[key] || '';

Будь ласка, не публікуйте декілька однакових відповідей на різні запитання. Там якісь - то корисні поради про цю практику тут
Девід Бак

Використовуйте це, якщо вам не потрібно мати справу зі змінами URL-адреси, тобто параметри вже доступні в поточній URL-адресі. Зробіть це спостережливим способом інакше.
tom

1

Якщо у вас порожній об’єкт маршруту, це пов'язано, головним чином, з тим, що ви не використовуєте маршрутизатор у своїй програмі app.component.html.

Без цього ви не зможете отримати значущий об’єкт маршруту з не порожніми суб'єктами, зокрема парами та queryParams.

Спробуйте додати <router-outlet><router-outlet>безпосередньо перед тим, як зателефонувати на ваш <app-main-component></app-main-component>

Перед цим переконайтеся, що ваш параметр запитів готовий до маршрутизації додатків>, який експортує клас маршруту, який використовується компонентом програми:

param: '/param/:dynamicParam', path: MyMainComponent

Останнє, звичайно, щоб отримати ваш парам, я особисто використовую this.route.snapshot.params.dynamicParamтам, де динамичний параметр - це ім'я, яке використовується у вашому компоненті маршрутизації додатків :)


1

Будьте обережні зі своїми маршрутами. "RedirectTo" видалить | скинути будь-який параметр запиту.

const appRoutes: Routes [
 {path: "one", component: PageOneComponent},
 {path: "two", component: PageTwoComponent},
 {path: "", redirectTo: "/one", pathMatch: full},
 {path: "**", redirectTo: "/two"}
]

Я закликав свій основний компонент із параметрами запиту на кшталт "/ main? Param1 = a & param2 = b і припускаю, що мої параметри запиту надходять у метод" ngOnInit () "в головному компоненті до початку переадресації переадресації.

Але це неправильно. Переспрямування буде раніше, відкине параметри запиту і викличе метод ngOnInit () у головному компоненті без параметрів запиту.

Я змінив третій рядок своїх маршрутів на

{path: "", component: PageOneComponent},

і тепер мої параметри запиту доступні в основних компонентах ngOnInit, а також у PageOneComponent.


1

Знайдено в: Батьківські компоненти отримують порожні параметри від ActivateRoute

Для мене працювали:

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

@Component({
  selector: 'app-navigation-bar',
  templateUrl: './navigation-bar.component.html',
  styleUrls: ['./navigation-bar.component.scss']
})
export class NavigationBarComponent implements OnInit, OnDestroy {
  private sub: any;
  constructor(private route: ActivatedRoute, private router: Router) {}

  ngOnInit() {
    this.sub = this.router.events.subscribe(val => {
      if (val instanceof RoutesRecognized) {
        console.log(val.state.root.firstChild.params);
      }
    });
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }

}

0

Просто натрапили на ту ж проблему, і більшість відповідей тут, здається, вирішують її лише для внутрішнього кутового маршрутизації, а потім деякі з них для параметрів маршруту, які не відповідають параметри запиту.

Я здогадуюсь, що я маю подібний випадок використання, як оригінальне запитання Ларса.

Для мене випадком використання є, наприклад, відстеження рефералів:

Кутовий запуск mycoolpage.com, з хеш-маршрутизацією, тому mycoolpage.comпереспрямовується на mycoolpage.com/#/. Для направлення, однак, таке посилання, яке також mycoolpage.com?referrer=fooповинно бути корисним. На жаль, Angular негайно знімає параметри запиту, переходячи безпосередньо до mycoolpage.com/#/.

Будь-який "трюк" із використанням порожнього компонента + AuthGuard та отримання queryParamsабо виконання queryParamMap, на жаль, не працює для мене. Вони завжди були порожніми.

Моє рішуче рішення вирішило обробляти це невеликим сценарієм, в index.htmlякому отримується повна URL-адреса з параметрами запиту. Потім я отримую значення парами запиту за допомогою маніпуляції з рядком і встановлюю його на об'єкт вікна. Потім окрема служба обробляє отримання ідентифікатора від об’єкта вікна.

скрипт index.html

const paramIndex = window.location.href.indexOf('referrer=');
if (!window.myRef && paramIndex > 0) {
  let param = window.location.href.substring(paramIndex);
  param = param.split('&')[0];
  param = param.substr(param.indexOf('=')+1);
  window.myRef = param;
}

Сервіс

declare var window: any;

@Injectable()
export class ReferrerService {

  getReferrerId() {
    if (window.myRef) {
      return window.myRef;
    }
    return null;
  }
}

0

Просте рішення

 // in routing file
       {
            path: 'checkout/:cartId/:addressId',
            loadChildren: () => import('./pages/checkout/checkout.module').then(m => m.CheckoutPageModule)
          },

    // in Component file

            import { Router, ActivatedRoute } from '@angular/router';

                 constructor(
                      private _Router: ActivatedRoute
                  ) { }

                  ngOnInit() {
                    this.cartId = this._Router.snapshot.params.cartId;
                    this.addressId = this._Router.snapshot.params.addressId;
                    console.log(this.addressId, "addressId")
                    console.log(this.cartId, "cartId")
                  }

0

http: // localhost: 4200 / products? order = popular

Ми можемо отримати доступ до парами запиту замовлення таким чином:

this.route.queryParams
      .filter(params => params.order)
      .subscribe(params => {
        console.log(params)// {order: "popular"}

        this.order = params.order;
        console.log(this.order); // popular
      });
  }

Також є queryParamMap, який повертає спостережуваний об'єкт paramMap.

Враховуючи таку URL-адресу маршруту:

http: // localhost: 4200 / products? order = popular & filter = new

this.route.queryParamMap.subscribe(params => {
  this.orderObj = {...params.keys, ...params};
});

Джерело - https://alligator.io/angular/query-parameters/


0

У, я думаю, кутовий 8:

ActivatedRoute.paramsбуло замінено на ActivatedRoute.paramMap ActivatedRoute.queryParamsзамінено ActivatedRoute.queryParamMap


-1
/*
Example below url with two param (type and name) 
URL : http://localhost:4200/updatePolicy?type=Medicare%20Insurance&name=FutrueInsurance
*/ 
  constructor(private route: ActivatedRoute) {
    //Read url query parameter `enter code here`
  this.route.queryParams.subscribe(params => {
    this.name= params['type'];
    this.type= params['name'];
    alert(this.type);
    alert(this.name);

 });

  }

-9

Якщо ви не використовуєте кутовий маршрутизатор, спробуйте виконати запит . Встановіть його

npm install --save querystring

до вашого проекту. У своєму компоненті зробіть щось подібне

import * as qs from 'querystring';
...
ngOnInit() {
   const params = qs.parse(window.location.search.substring(1));
   ...
}

Це substring(1)необхідно, тому що якщо у вас є щось подібне, '/mypage?foo=bar'то ключовим ім'ям буде?foo

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.