Açısal: Route değiştirmeden queryParams nasıl güncellenir?


127

Bir bileşenden queryParams'i güncellemeye (eklemeye, kaldırmaya) çalışıyorum. AngularJS'de, aşağıdakiler sayesinde mümkündü:

$location.search('f', 'filters[]'); // setter
$location.search()['filters[]'];    // getter

Kullanıcının filtreleyebileceği, sipariş edebileceği vb. Bir listeye sahip bir uygulamam var ve url'nin tüm aktif filtrelerini sorguda ayarlamak istiyorum, böylece url'yi kopyalayabilir / yapıştırabilir veya başka biriyle paylaşabilir.

Ancak, her filtre seçildiğinde sayfamın yeniden yüklenmesini istemiyorum .

Bu yeni yönlendirici ile yapılabilir mi?

Yanıtlar:


273

Sayfanızı yeniden yüklemeyecek, ancak sorgu parametrelerini güncelleyecek olan yeni sorgu parametreleriyle mevcut rotaya gidebilirsiniz.

(Bileşende) gibi bir şey:

constructor(private router: Router) { }

public myMethodChangingQueryParams() {
  const queryParams: Params = { myParam: 'myNewValue' };

  this.router.navigate(
    [], 
    {
      relativeTo: activatedRoute,
      queryParams: queryParams, 
      queryParamsHandling: 'merge', // remove to replace all query params by provided
    });
}

Sayfayı yeniden yüklemeyecek olsa da, tarayıcının geçmişine yeni bir giriş göndereceğini unutmayın. Oraya yeni bir değer eklemek yerine onu geçmişte değiştirmek isterseniz kullanabilirsiniz { queryParams: queryParams, replaceUrl: true }.

DÜZENLEME: Yorumlarda daha önce belirtildiği gibi []ve relativeToorijinal örneğimde özellik eksikti, bu nedenle sadece sorgu parametrelerini değil, rotayı da değiştirmiş olabilir. this.router.navigateBu durumda doğru kullanım:

this.router.navigate(
  [], 
  {
    relativeTo: this.activatedRoute,
    queryParams: { myParam: 'myNewValue' },
    queryParamsHandling: 'merge'
  });

Yeni parametre değerinin olarak ayarlanması, parametrenin nullURL'den kaldırılmasına neden olur.


30
Ben kullanmak zorunda []yerine ['.']çalışması için
Jaime Gomez

5
QueryParams ['relativeTo'] = this.activatedRoute; navigasyonu geçerli sayfaya göre yapmak için
klonq

3
OP'nin problemini çözmek için güzel bir çözüm. Bir şeyi kaçırmadığım sürece, sizi anlamayan şey, geçerli sayfanın geçmişinizde geri ve ileri gitme (örneğin, her biri kendi URL'sine sahip ancak aynı bileşene sahip 5 kez filtre veya sıra değiştirilmiş) ve sayfanın içeriği, bu 5 URL'ye doğrudan erişirseniz nasıl olacağını gösterir. Bunu manuel olarak gerçekleştirebileceğinizi this.activatedRoute.queryParams.subscribeve bileşeninizde çeşitli güncellemeler yapabileceğinizi düşünüyorum , ancak geri ve ileri otomatik olarak çalışacak şekilde rotayı yüklemenin basit bir Açısal yolu var mı?
jmq

1
yönlendiriciyi kullanırken. navigate pencerenin üst kısmına kayacaktır, bunun nasıl devre dışı bırakılacağı hakkında herhangi bir fikriniz var mı?
Hese

1
@Hese, emin misin? En üste kayacağını sanmıyorum. Lütfen şu örneğe bir göz atın: stackblitz.com/edit/angular-sdtsew?file=src/app/…
Radosław Roszkowiak

23

@ Radosław Roszkowiak'ın cevabı, relativeTo: this.routeaşağıdaki gibi gerekli olması dışında neredeyse doğrudur :

constructor(
  private router: Router,
  private route: ActivatedRoute,
) {}

changeQuery() {
  this.router.navigate(['.'], { relativeTo: this.route, queryParams: { ... }});
}

14

Angular 5'te , mevcut url'yi ayrıştırarak urlTree'nin bir kopyasını kolayca elde edebilir ve değiştirebilirsiniz . Bu, sorgu parametrelerini ve parçalarını içerecektir.

  let urlTree = this.router.parseUrl(this.router.url);
  urlTree.queryParams['newParamKey'] = 'newValue';

  this.router.navigateByUrl(urlTree); 

Bir sorgu parametresi değiştirmek için "doğru yolu" ile muhtemelen createUrlTree bize kullanarak değiştirmek izin verirken akımından yeni UrlTree oluşturur gibi aşağıda NavigationExtras .

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

constructor(private router: Router) { }

appendAQueryParam() {

  const urlTree = this.router.createUrlTree([], {
    queryParams: { newParamKey: 'newValue' },
    queryParamsHandling: "merge",
    preserveFragment: true });

  this.router.navigateByUrl(urlTree); 
}

Bir sorgu parametresini bu şekilde kaldırmak için undefinedveya olarak ayarlayabilirsiniz null.


2
navigateByUrlfarklıdır navigate- sadece UrlTree parametresiyle değil. Bkz stackoverflow.com/a/45025432/271012
Drenai

9

Deneyin

this.router.navigate([], { 
  queryParams: {
    query: value
  }
});

tek tırnaklar dışında aynı rota navigasyonu için çalışacaktır.


Tam olarak bu şeyi arıyordum. Teşekkür ederim!!!
cevaris

7

En çok oy alan cevap kısmen benim için çalıştı. Tarayıcı url'si aynı kaldı, ancak routerLinkActivenavigasyondan sonra artık çalışmıyordu.

Benim çözümüm lotation.go kullanmaktı:

import { Component } from "@angular/core";
import { Location } from "@angular/common";
import { HttpParams } from "@angular/common/http";

export class whateverComponent {
  constructor(private readonly location: Location, private readonly router: Router) {}

  addQueryString() {
    const params = new HttpParams();
    params.append("param1", "value1");
    params.append("param2", "value2");
    this.location.go(this.router.url.split("?")[0], params.toString());
  }
}

HttpParams kullanarak sorgu dizesini httpClient ile bilgi göndermek için kullandığımdan beri kullandım. ama kendiniz inşa edebilirsiniz.

ve, this._router.url.split("?")[0]önceki tüm sorgu dizelerini geçerli url'den kaldırmaktır.


4
Bu kabul edilen cevap olmalıdır, router.navigates ayrıca ngOnit'i de yeniler, location.go bunu YAPMAZ! Bu gerçekten önemlidir, çünkü bileşeniniz bazı ngOnit mantığı (HTTP çağrıları vb.) Yaparsa, router.navigate'i kullandığınızda tekrar çağrılacaktır. Bunu istemezsin.
Danny Hoeve

Neden yalnızca url için yönlendiriciye ihtiyacınız var? this.location.path().split...Daha iyi değil mi?
Vladimir

@Vladimir haklı olabilirsin, bileşenimde başka amaçlarla kullanıyordum, bu yüzden sadece bunun için değildi. Yine de doğrulamak için zamanım yok.
moi_meme

Örneğin promosyon veya google izleme parametreleri gibi sorgu parametrelerini korumak istiyorsanız bu çalışmayacaktır
Jon Tinsman 18-19

6

Ben birleştirerek sona erdi urlTreeilelocation.go

const urlTree = this.router.createUrlTree([], {
       relativeTo: this.route,
       queryParams: {
           newParam: myNewParam,
       },
       queryParamsHandling: 'merge',
    });

    this.location.go(urlTree.toString());

toStringSorunlara yol açıp açmayacağından emin değilim , ancak maalesef location.godizge tabanlı görünüyor.


4

Yolu değiştirmeden sorgu parametrelerini değiştirmek istiyorsanız. aşağıdaki örneğe bakın size yardımcı olabilir: mevcut rota: / search & Hedef rota (sayfayı yeniden yükleme olmadan): / search? query = love

submit(value: string) {
{ this.router.navigate( ['.'],  { queryParams: { query: value } })
    .then(_ => this.search(q));
}
search(keyword:any) { 
//do some activity using }

lütfen dikkat: this.router.navigate (['arama'] yerine this.router.navigate (['.']


[.] Seçeneğinin daha iyi bir yaklaşım olduğundan emin değilim relativeTo:, ancak .then()yardımcı oldu - navigate () 'in bir söz verdiğinin farkında değildi, gönderdiğinize çok sevindim!
Drenai

0

Öncelikle, yönlendirici modülünü açısal yönlendiriciden içe aktarmalı ve takma adını bildirmeliyiz.

import { Router } from '@angular/router'; ---> import
class AbcComponent implements OnInit(){
constructor(
    private router: Router ---> decalre alias name
  ) { }
}

1. "router.navigate" işlevini kullanarak sorgu parametrelerini değiştirebilir ve sorgu parametrelerini iletebilirsiniz

this.router.navigate([], { queryParams: {_id: "abc", day: "1", name: "dfd"} 
});

Geçerli yani etkinleştirilen rotadaki sorgu parametrelerini güncelleyecektir.

  1. Aşağıdakiler, sorgu parametreleri olarak _id, gün ve ad ile abc sayfasına yeniden yönlendirecektir.

    this.router.navigate (['/ abc'], {queryParams: {_id: "abc", day: "1", name: "dfd"}});

    "Abc" yolundaki sorgu parametrelerini üç sorgu parametresiyle birlikte günceller

Sorgu parametrelerini getirmek için: -

    import { ActivatedRoute } from '@angular/router'; //import activated routed

    export class ABC implements OnInit {

    constructor(
        private route: ActivatedRoute //declare its alias name
      ) {}

    ngOnInit(){
       console.log(this.route.snapshot.queryParamMap.get('_id')); //this will fetch the query params
    }
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.