Angular 2 url sorgu params almak nasıl?


237

Açısal 2.0.0-beta.7 kullanıyorum. Bir bileşen /path?query=value1, yönlendirildiği gibi bir yola yüklendiğinde /path. GET parametreleri neden kaldırıldı? Parametreleri nasıl koruyabilirim?

Yönlendiricilerde bir hata var. Gibi bir ana rotam varsa

@RouteConfig([
  {
      path: '/todos/...',
      name: 'TodoMain',
      component: TodoMainComponent
  }
])

ve çocuğumun rotası şöyle

@RouteConfig([
  { path: '/', component: TodoListComponent, name: 'TodoList', useAsDefault:true },
  { path: '/:id', component: TodoDetailComponent, name:'TodoDetail' }
])

sonra TodoListComponent params alamıyorum. Alabilirim

params("/my/path;param1=value1;param2=value2") 

ama klasiği istiyorum

query params("/my/path?param1=value1&param2=value2")

1
bunun @RouteConfigiçin nasıl belirttiniz path?
Pankaj Parkar

Hata buldum. Ana yol ve alt yol var ve {path: '/ todos / ...' gibi ana yol varsa, adı: 'TodoMain', bileşen: TodoMainComponent} ve alt yol {path: '/', bileşen: TodoListComponent, name: 'TodoList', useAsDefault: true}, işe yaramaz ve sorgu parametreleri olmadan url'ye yönlendirir.
FireGM

Yanıtlar:


412

ActivatedRouteBirinin bir örneğini enjekte etmek , a queryParamsve bir paramsgözlemlenebilir dahil olmak üzere çeşitli gözlenebilirlere abone olabilir :

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

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

  constructor(private activatedRoute: ActivatedRoute) {}

  ngOnInit() {
    // Note: Below 'queryParams' can be replaced with 'params' depending on your requirements
    this.activatedRoute.queryParams.subscribe(params => {
        const userId = params['userId'];
        console.log(userId);
      });
  }

}

ABONE OLMAYAN BİR NOT

@Reto ve @ codef0rmer, resmi belgelere göre bu örnekte unsubscribe()bileşenlerin içinde bir onDestroy()yöntemin gerekli olmadığını oldukça haklı olarak belirtmişlerdir . Bu kod örneğimden kaldırıldı. ( bu eğiticideki mavi uyarı kutusuna bakın )


2
Ayrıca bu özel durumda aboneliği bir söz ile değiştirmenizi öneririm. this.activatedRoute.params.toPromise (). sonra (yanıt => ...) .catch (hata => ...);
Aralık

"ActivatedRoute" i nerede iletebilirim?
michali

20
Resmi belgelerden: Aboneliği iptal etmem gerekiyor mu? The Router manages the observables it provides and localizes the subscriptions. The subscriptions are cleaned up when the component is destroyed, protecting against memory leaks, so we don't need to unsubscribe from the route params Observable.
Reto

aboneliği (veya sözünü) tetiklemeden açısal yönlendirmeler. Belirteç ile orijinal oAUth geri arama görebilirsiniz, ancak sonra sorgu params ve console.log (param) sadece boş bir nesne olmadan rotaya yönlendirir.
FlavorScape

1
@Sobhan, evet bir fark var. SwitchMap işleci bir Gözlemlenebilir döndürürken abone işleci gözlemcinin (bileşenimiz) Nihayetinde bir Gözlemlenebilir tarafından gönderilen öğeleri görmesine izin verir. Dolayısıyla dokümanlarda 2 anahtarlama haritası örneği var. 1) Kahramanlar için istek eklemek üzere switchMap kullandılar. SwitchMap, abone olmanın aksine, kullanıcı yine de bir kahraman alırken rotaya tekrar gitmesi durumunda isteğin iptal edilmesini sağlar. 2) Bir asenkron boru kullanılır. Zaman uyumsuz borular gözlemlenebilir, bu nedenle abone olmamanız gerekir (Zaman uyumsuz boru bunu sizin için yapar).
Stephen Paul

103

Böyle bir URL ne zaman http://stackoverflow.com?param1=value

Aşağıdaki kod ile param1 alabilirsiniz:

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

@Component({
    selector: '',
    templateUrl: './abc.html',
    styleUrls: ['./abc.less']
})
export class AbcComponent implements OnInit {
    constructor(private route: ActivatedRoute) { }

    ngOnInit() {
        // get param
        let param1 = this.route.snapshot.queryParams["param1"];
    }
}

2
bu artık routeconfig yoluna "/: id" eklemenize gerek olmadığı anlamına mı geliyor? çünkü bunu kullandığımda "tanımsız" alıyorum, bu yüzden hala bir yerde bir hatayla karşılaşmalıyım
Axelle

2
Harika. Bu, dinamik bir sunucu url'sinden doğrudan paramleri okumam gerektiğinden aradım. Gezinmeyi kullanamıyorum.
Ayı

37

Soru beta 7 sürümünü belirtmesine rağmen , bu soru açısal 2 sorgu parametreleri gibi yaygın ifadeler için Google'da en iyi arama sonucu olarak karşımıza çıkmaktadır . Bu nedenle en yeni yönlendirici (şu anda alpha.7'de ) için bir cevap .

Parametrelerin okuma şekli önemli ölçüde değişti. Öncelikle Routeryapıcı parametrelerinizde çağrılan bağımlılığı enjekte etmeniz gerekir :

constructor(private router: Router) { }

ve bundan sonra ngOnInitmetodumuzdaki sorgu parametreleri için abone olabiliriz (yapıcı da iyidir, ancak ngOnInittest edilebilirlik için kullanılmalıdır)

this.router
  .routerState
  .queryParams
  .subscribe(params => {
    this.selectedId = +params['id'];
  });

Bu örnekte URL gibi sorgu parametresi kimliğini okuyoruz example.com?id=41.

Dikkat edilmesi gereken birkaç şey var:

  1. paramsLike özelliğine erişmek params['id']her zaman bir dize döndürür ve bu, önüne önek eklenerek sayıya dönüştürülebilir +.
  2. Sorgu parametrelerinin gözlemlenebilir şekilde getirilmesinin nedeni, yeni bir bileşen yüklemek yerine aynı bileşen örneğinin yeniden kullanılmasına izin vermesidir. Her sorgu parametresi değiştiğinde, abone olduğumuz yeni bir olaya neden olur ve bu nedenle değişikliklere buna göre tepki verebiliriz.

Aynı üyeye giden birden fazla parametrenin olmasının bir yolu var mı? Örneğin, 'id' ya da 'kimlik' 'in buna gitmek istiyorum. SelectedId.
phandinhlan

@phandinhlan: Bu gerçekten Açısal 2 ile ilgili bir soru değil. Elbette uygulanabilir, ama mantığı kendiniz tanımlamanız gerekir. Temel olarak, ilk anahtarın tanımlanıp tanımlanmadığını kontrol etmek ve ancak bundan sonra değeri ondan okumak ve eğer değilse, değeri başka bir anahtarla okumaktır. Bu gibi bir şeyle elde edilebilir if (params.hasOwnProperty('id')) { this.selectedId = params['id'] } else { this.selectedId = params['identification']}.
Roope Hakulinen

Evet sonunda böyle bir şey yaptım. Ben sadece "yerleşik" bir şekilde olacağını düşündüm: this.selectedId = + params ['id']; this.selectedId = + params ['tanımlama']; Tabii ki bu hiç mantıklı değil ve işe yaramıyor.
phandinhlan

28

@ StevePaul'un cevabını gerçekten beğendim, ancak aynı şeyi harici abone / abonelikten çıkma olmadan da yapabiliriz.

import { ActivatedRoute } from '@angular/router';
constructor(private activatedRoute: ActivatedRoute) {
    let params: any = this.activatedRoute.snapshot.params;
    console.log(params.id);
    // or shortcut Type Casting
    // (<any> this.activatedRoute.snapshot.params).id
}

7
elbette bununla ilgili uyarı, başlangıç ​​değeri olacağı ve sonraki değişikliklerin yansıtılmayacağıdır. URL parametrelerini mantığınızın bir parçası olarak programlı olarak değiştiriyorsanız, bilmeniz gereken bir şey var
ambidexterous

Bunun Angular'ın sonraki sürümleriyle değişip değişmediğinden emin değilim, ancak şimdi bunu this.activatedRoute.snapshot.queryParams
Michael

21

Sorgu parametreleri göndermek için

import { Router } from '@angular/router';
this.router.navigate([ '/your-route' ], { queryParams: { key: va1, keyN: valN } });

Sorgu parametrelerini almak için

import { ActivatedRoute } from '@angular/router';
this.activatedRoute.queryParams.subscribe(params => {
    let value_1 = params['key'];
    let value_N = params['keyN'];
});

Resmi kaynak


Okuma gayet iyi çalışıyor ancak büyük / küçük harfe duyarlıdır. Bu durumu nasıl duyarsız hale getirebiliriz?
Unnie

12

Merhaba URLSearchParams'ı kullanabilirsiniz, burada daha fazla bilgi edinebilirsiniz .

ithalat:

import {URLSearchParams} from "@angular/http";

ve fonksiyon:

getParam(){
  let params = new URLSearchParams(window.location.search);
  let someParam = params.get('someParam');
  return someParam;
}

Uyarı : Tüm platformlar tarafından desteklenmemektedir ve açısal dokümanlar tarafından "DENEYSEL" durumda görünmektedir


2
Bu benim için işe yaramıyor. Window.location.search, querystring parametrelerinin önde gelen soru işaretini içeriyor. Bu nedenle, ilk parametrenin anahtarı soru işaretinin başına eklenecektir.
AJ Morris

AJ Morris, sorununuzu if (window.location.search.indexOf('?') == 0){ normalizedQueryString = window.location.search.substring(1); } else { normalizedQueryString = window.location.search; } let params = new URLSearchParams(normalizedQueryString);
çözmek

URLSearchParams kullanımdan kaldırıldı. Şimdi ActivatedRoute ile yapabilirsiniz.
Robert Blasco Villarroya

7

İlk uzakta, ne Angular2 ile çalışan bulduk bir sorgu dizesi ile url olur /path;query=value1

Bu bileşene erişmek için kullandığınız bileşen Budur, ancak şimdi bir kod bloğunu izler:

    constructor(params: RouteParams){
    var val = params.get("query");
    }

Bileşeni yüklediğinizde neden kaldırılacağı konusunda, bu varsayılan davranış değildir. Temiz bir test projesinde özel olarak kontrol ettim ve yönlendirmedim veya değiştirmedim. Varsayılan bir rota mı yoksa rota hakkında özel bir şey mi?

Https://angular.io/docs/ts/latest/guide/router.html#!#query-parameters adresindeki Angular2 Öğreticisi'nde sorgu dizeleri ve parametrelerle yönlendirme hakkında bilgi edinin


"; Param1 = değer1; param2 = değer2" gibi parametreler kullanamıyorum, bu bağlantı başka bir sitede oluşturuldu ve "example.com/auth?code_for_auth=askjfbkajdsbfksajdf" gibi siteme yönlendiriyorum
Şubat'ta FireGM 28:16

Yönlendirmenin şu anda Angular2'de ayarlanma şekli, gerçekten mümkün olduğunu düşünmüyorum. Alt yönlendirme, matris url'sine bağlı olduğundan bir tür geçici çözüm gerekli olacaktır. En azından bildiğim gibi. Bunu web
sunucumda keser

Bağlama sitesinden URL'lerini değiştirmesini isteme imkanınız yok mu?
Namirna

1
Hayır. Ancak sorunu kolayca
çözdüm

4
bu çözüm kullanımdan kaldırıldı!

7

Aşağıda belirtildiği gibi ActivatedRoute'u kullanarak URL'ye iletildiğinde sorgu parametrelerini alabilirsiniz: -

url: - http: /etkialanı.com? test = abc

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

@Component({
  selector: 'my-home'
})
export class HomeComponent {

  constructor(private sharedServices : SharedService,private route: ActivatedRoute) { 
    route.queryParams.subscribe(
      data => console.log('queryParams', data['test']));
  }

}

7

URL parametresini nesne olarak alın.

import { Router } from '@angular/router';
constructor(private router: Router) {
    console.log(router.parseUrl(router.url));
}

2

Sorgu parametresini yalnızca bir kez almak istiyorsanız, aboneliği iptal etme konusunda endişelenmenize gerek kalmadan en iyi yol take yöntemini kullanmaktır . İşte basit snippet: -

constructor(private route: ActivatedRoute) {
  route.snapshot.queryParamMap.take(1).subscribe(params => {
     let category = params.get('category')
     console.log(category);
  })
}

Not: İleride parametre değerlerini kullanmak istiyorsanız take (1) 'i kaldırın .


2

şimdi:

this.activatedRoute.queryParams.subscribe((params: Params) => {
  console.log(params);
});

1
Kısa süreli sınırlı yardım sağlayabilecek bu kod snippet'i için teşekkür ederiz. Düzgün bir açıklama , bunun neden problem için iyi bir çözüm olduğunu göstererek uzun vadeli değerini büyük ölçüde artıracak ve diğer benzer sorularla gelecekteki okuyucular için daha yararlı hale getirecektir. Yaptığınız varsayımlar dahil bazı açıklamalar eklemek için lütfen cevabınızı düzenleyin
Shawn C.

1

Umarım başka birine yardımcı olur.

Yukarıdaki soru, sayfa yeniden yönlendirildikten sonra sorgu parametresi değerinin gerekli olduğunu belirtir ve anlık görüntü değerinin (gözlemlenemez alternatif) yeterli olacağını varsayabiliriz.

Burada kimse resmi belgelerden snapshot.paramMap.get hakkında bahsetmedi .

this.route.snapshot.paramMap.get('id')

Bu yüzden göndermeden önce bunu gönderme / yeniden yönlendirme bileşenine ekleyin:

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

daha sonra yeniden yönlendirin ( burada belgelenmiştir ):

this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]);

ya da sadece:

this.router.navigate(['/heroes', heroId ]);

Bunu, burada belgelendiği gibi yönlendirme modülünüze eklediğinizden emin olun :

 { path: 'hero/:id', component: HeroDetailComponent }

Ve son olarak, bileşeninizde sorgu parametresini kullanması gereken

  • ithalat ekleyin ( burada belgelenmiştir ):

    import { Router, ActivatedRoute, ParamMap } from '@angular/router';
  • ActivatedRoute enjekte edin

(belgeler switchMap'i de içe aktarır ve ayrıca Router ve HeroService'i enjekte eder - ancak bunlar yalnızca gözlemlenebilir alternatif için gereklidir - bizim durumumuzda olduğu gibi anlık görüntü alternatifini kullandığınızda gerekli DEĞİLDİR):

    constructor(
      private route: ActivatedRoute
    ) {}
  • ve ihtiyacınız olan değeri elde edin ( burada belgelenmiştir ):

    ngOnInit() {
      const id = this.route.snapshot.paramMap.get('id');
    }

NOT: BİR ÖZELLİK MODÜLÜNE (DOKÜMANTASYONDA GÖSTERİLDİĞİ GİBİ) YÖNLENDİRME MODÜLÜ EKLerseniz, UYGULAMA MODUNUN İTHALAT ÖNCE GELDİĞİNDEN EMİN OLUN: []. Aksi takdirde ÖZELLİK ROTALARI BULUNMAYACAKTIR ({path: '**' SONRASI GELECEKTİR, yönlendirme: '/ bulunamadı') ve yalnızca bulunamadı iletisini görürsünüz).


1

Sadece yapıcıya ActivatedRoute enjekte etmeniz ve sonra sadece params veya queryParams'a erişmeniz yeterlidir.

constructor(private route:ActivatedRoute){}
ngOnInit(){
        this.route.queryParams.subscribe(params=>{
        let username=params['username'];
      });
 }

Bazı durumlarda NgOnInit'te bir şey vermez ... belki de bu durumda paramların başlatılmasından önce init çağrısı nedeniyle debounceTime (1000) tarafından bir süre beklemesini gözlemleyerek bunu başarabilirsiniz.

örneğin =>

 constructor(private route:ActivatedRoute){}
    ngOnInit(){
            this.route.queryParams.debounceTime(100).subscribe(params=>{
            let username=params['username'];
          });
     }

debounceTime () Yalnızca belirli bir zaman aralığı başka bir kaynak emisyonu olmadan geçtikten sonra gözlemlenebilir bir değer üretir


0

RouterState'ten rotada tanımlanmamışsa bir parametre alamazsınız, bu nedenle örneğin, sorgu dizesini ayrıştırmanız gerekir ...

İşte kullandığım kod:

let re = /[?&]([^=#&]+)=([^&#]*)/g;
let match;
let isMatch = true;
let matches = [];
while (isMatch) {
    match = re.exec(window.location.href);
    if (match !== null) {
        matches[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
        if (match.index === re.lastIndex) {
            re.lastIndex++;
        }
    }
    else {
        isMatch = false;
    }
}
console.log(matches);


0

Sorgu ve Yol (Açısal 8)

Https://myapp.com/owner/123/show?height=23 gibi bir URL'niz varsa kullanın

combineLatest( [this.route.paramMap, this.route.queryParamMap] )
  .subscribe( ([pathParams, queryParams]) => {
    let ownerId = pathParams.get('ownerId');    // =123
    let height  = queryParams.get('height');    // =height
    // ...
  })

GÜNCELLEME

Kullandığınız this.router.navigate([yourUrl]);ve sorgu parametrelerinizin yourUrldizeye gömülü olması durumunda açısal bir URL kodlar ve böyle bir şey alırsanız https://myapp.com/owner/123/show%3Fheight%323 - ve yukarıdaki çözüm yanlış sonuç verecektir ( queryParams boş olacak ve sorgu uçları yolun ucundaysa son yol parametresine yapıştırılabilir). Bu durumda navigasyon biçimini değiştirmek Buna

this.router.navigateByUrl(yourUrl);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.