Angular : 경로를 변경하지 않고 queryParams를 업데이트하는 방법


126

구성 요소에서 queryParams를 업데이트 (추가, 제거)하려고합니다. angularJS에서는 다음 덕분에 가능했습니다.

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

사용자가 필터링, 주문 등을 할 수있는 목록이있는 앱이 있으며 URL의 queryParams에 활성화 된 모든 필터를 설정하여 URL을 복사 / 붙여 넣기하거나 다른 사람과 공유 할 수 있습니다.

그러나 필터를 선택할 때마다 내 페이지가 다시로드되는 것을 원하지 않습니다 .

새로운 라우터로 가능합니까?

답변:


272

페이지를 다시로드하지 않지만 쿼리 매개 변수를 업데이트하는 새 쿼리 매개 변수를 사용하여 현재 경로로 이동할 수 있습니다.

다음과 같은 것 (구성 요소에서) :

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

페이지를 다시로드하지는 않지만 브라우저 기록에 새 항목을 푸시합니다. 새 값을 추가하는 대신 기록에서 대체하려면 { queryParams: queryParams, replaceUrl: true }.

편집 :로 이미 의견에서 지적 []하고 relativeTo그것뿐만 아니라 쿼리 PARAMS을 경로를 변경 수 있도록 속성이, 내 원래의 예에서 누락되었습니다. this.router.navigate이 경우 적절한 사용법은 다음과 같습니다.

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

새 매개 변수 값을로 설정하면 nullURL에서 매개 변수 가 제거됩니다.


30
내가 사용했다 []대신 ['.']작동하도록
제이미 고메즈

5
queryParams [ 'relativeTo']를 사용해야 함 = this.activatedRoute; 현재 페이지를 기준으로 탐색을 만들기 위해
klonq

3
OP의 문제를 해결하기위한 좋은 솔루션입니다. 내가 뭔가를 놓치지 않는 한, 그것이 당신을 얻지 못하는 것은 현재 페이지의 역사에서 앞뒤로 이동할 수 있다는 것입니다 (예 : 변경된 필터 또는 순서 5 번, 각각 고유의 URL을 가지지 만 동일한 구성 요소를 가짐). 페이지의 콘텐츠는 5 개의 URL에 직접 액세스 한 경우와 같이 표시됩니다. 수동으로이를 수행 this.activatedRoute.queryParams.subscribe하고 구성 요소에서 다양한 업데이트 를 수행 할 수 있다고 생각 하지만, 앞뒤로 자동으로 작동하도록 경로를로드하는 간단한 Angular 방법이 있습니까?
jmq

1
router.navigate를 사용할 때 창 상단으로 스크롤됩니다.이 기능을 비활성화하는 방법이 있습니까?
Hese

1
@Hese, 확실합니까? 나는 그것이 맨 위로 스크롤되지 않을 것이라고 생각합니다. 이 예에서 봐 주시기 바랍니다 : stackblitz.com/edit/angular-sdtsew?file=src/app/...
Radosław Roszkowiak

23

@ Radosław Roszkowiak의 대답은 relativeTo: this.route아래와 같이 필요한 것을 제외하고 거의 옳습니다 .

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

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

14

Angular 5에서는 현재 URL을 구문 분석하여 urlTree 의 복사본을 쉽게 얻고 수정할 수 있습니다 . 여기에는 쿼리 매개 변수와 조각이 포함됩니다.

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

  this.router.navigateByUrl(urlTree); 

쿼리 매개 변수를 수정하는 "올바른 방법"은과 아마 createUrlTree 우리가 사용하여 수정시키는 동안 현재에서 새 UrlTree을 만들어 같은 그 이하 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); 
}

이 방법으로 쿼리 매개 변수를 제거하려면 undefined또는로 설정할 수 있습니다 null.


2
navigateByUrldiffreent가하는 것입니다 navigate뿐만 아니라 UrlTree의 PARAM와 -. 참조 stackoverflow.com/a/45025432/271012
Drenai

9

시험

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

작은 따옴표가 아닌 동일한 경로 탐색에서 작동합니다.


나는이 정확한 것을 찾고 있었다. 감사합니다!!!
cevaris

7

대부분의 투표에 대한 답변은 부분적으로 저에게 효과적이었습니다. 브라우저 URL은 동일하게 유지되었지만 routerLinkActive탐색 후 더 이상 작동하지 않았습니다.

내 해결책은 로션을 사용하는 것이 었습니다.

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

이미 httpClient로 정보를 보내는 데 사용하고 있었으므로 HttpParams를 사용하여 쿼리 문자열을 작성했습니다. 하지만 직접 만들 수 있습니다.

그리고 this._router.url.split("?")[0], 현재의 URL에서 이전의 모든 쿼리 문자열을 제거하는 것입니다.


4
이것은 허용되는 대답이어야하며 router.navigates는 ngOnit도 새로 고칩니다. location.go는 이것을 수행하지 않습니다! 구성 요소가 일부 ngOnit 로직 (HTTP 호출 등)을 수행하면 router.navigate를 사용할 때 다시 호출되기 때문에 이것은 매우 중요합니다. 당신은 이것을 원하지 않습니다.
Danny Hoeve

URL 전용 라우터가 필요한 이유는 무엇입니까? 아닌가 this.location.path().split...더 나은?
Vladimir

@Vladimir 당신이 옳을 수 있습니다. 내 구성 요소에서 다른 목적으로 사용하고 있었으므로 그 뿐만이 아닙니다. 그래도 확인할 시간이 없습니다.
moi_meme

예를 들어 프로모션 또는 Google 추적 매개 변수와 같은 쿼리 매개 변수를 보존하려는 경우에는 작동하지 않습니다.
Jon

5

나는 결국 결합 urlTree했다location.go

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

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

toString문제를 일으킬 수 있는지 확실하지 않지만 불행히도 location.go문자열 기반으로 보입니다.


4

경로를 변경하지 않고 쿼리 매개 변수를 변경하려는 경우. 아래 예제를 참조하면 도움이 될 수 있습니다. 현재 경로는 : / search & 대상 경로는 (페이지를 다시로드하지 않음) : / search? query = love

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

참고 : this.router.navigate ([ '.'] 대신 this.router.navigate ([ 'search']) 를 사용할 수 있습니다 .


[.]이보다 나은 접근 방식 인지는 relativeTo:모르겠지만이 ( .then()가) 도움이되었습니다. navigate ()가 프라 미스를 반환했다는 사실을 몰랐 으므로 게시 해 주셔서 감사합니다!
Drenai

0

먼저 앵귤러 라우터에서 라우터 모듈을 가져와 별칭 이름을 선언해야합니다.

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

1. "router.navigate"기능을 사용하여 쿼리 매개 변수를 변경하고 쿼리 매개 변수를 전달할 수 있습니다.

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

현재 활성화 된 경로에서 쿼리 매개 변수를 업데이트합니다.

  1. 아래는 쿼리 매개 변수로 _id, 요일 및 이름이있는 abc 페이지로 리디렉션됩니다.

    this.router.navigate ([ '/ abc'], {queryParams : {_id : "abc", 요일 : "1", 이름 : "dfd"}});

    세 개의 쿼리 매개 변수와 함께 "abc"경로의 쿼리 매개 변수를 업데이트합니다.

쿼리 매개 변수를 가져 오는 경우 :-

    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
    }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.