Angular 2에서 다시로드하지 않고 경로 매개 변수 변경


113

저는 Angular 2, Google Maps 등을 사용하여 부동산 웹 사이트를 만들고 있으며 사용자가지도의 중심을 변경하면지도의 현재 위치와 반경을 나타내는 API를 검색합니다. 문제는 전체 페이지를 다시로드하지 않고 URL에 해당 값을 반영하고 싶습니다. 가능합니까? AngularJS 1.x를 사용하는 몇 가지 솔루션을 찾았지만 Angular 2에 대해서는 아무것도 찾지 못했습니다.


[routerLink] = "[ '/ route', {param1 : value1}]을 사용하면 페이지가 다시로드되지 않을 것 같습니다
Toolkit

하지만 다른 쿼리 매개 변수를 어떻게 추가 할 수 있습니까?
툴킷

2
☝️ 페이지
새로

SSR을 사용하여 사이트 SEO를 호환 가능하게 만드는 경우 이것은 논쟁의 여지가 있습니다.
Jonathan

@ 조나단, 맞습니까? Angular는 정적 페이지가 렌더링되면 라우팅을 인수하므로 SSR을 사용할 때도 여전히 유효한 질문이라고 생각합니다.
adam0101

답변:


91

당신은 사용할 수 있습니다 location.go(url)기본적으로 응용 프로그램의 경로에 변화없이, 당신의 URL을 변경 것이다.

참고 이것은 현재 경로에서 자식 경로로 리디렉션과 같은 다른 효과를 유발할 수 있습니다.

설명하는 관련 질문location.goRouter변경 사항이 발생하지 않습니다.


2
내 경로에는 검색 필드의 직렬화 된 버전을 수신하는 'search'라는 매개 변수가 있습니다. 목록 상태가 처음로드 될 때 this._routeParams.get ( 'search')를 사용하여 해당 매개 변수 만 읽고 필터를 역 직렬화합니다. 검색을 수행합니다. 사용자가지도 또는 검색 패싯을 사용하여 검색 필드를 변경하면 라우터의 생성 메소드를 사용하여 올바른 URL을 구성합니다. var instruction = this._router.generate ([ 'Listing', {search : serializedFields}] ) 그런 다음 this._location.go (instruction.urlPath)를 사용하여 상태를 다시로드하지 않고 URL을 변경합니다.
Marcos Basualdo

20
다른 사람이 궁금해하는 경우 : import {Location} from 'angular2 / platform / common';
Kesarion

18
import { Location } from '@angular/common';각도 4
tehCivilian

2
당신은 같은 constructr decared나요constructor(private location: Location){ }
판 카즈 Parkar

2
@AdrianE 문제는 아마도 입력 location.go()해야 할 때 입력했을 것입니다 this.location.go(). 를 내보낼 때 this.Typescript의 위치 인터페이스를 호출합니다.
georg-un

94

RC6부터 상태를 변경하지 않고 URL을 변경하여 경로 기록을 유지하려면 다음을 수행 할 수 있습니다.

import {OnInit} from '@angular/core';

import {Location} from '@angular/common'; 
// If you dont import this angular will import the wrong "Location"

@Component({
  selector: 'example-component',
  templateUrl: 'xxx.html'
})
export class ExampleComponent implements OnInit
{
  constructor( private location: Location )
  {}

  ngOnInit()
  {    
    this.location.replaceState("/some/newstate/");
  }
}

이것은 나를 위해 작동하지 않습니다. 경로를로드하려고 시도합니다. 콘솔 오류 :Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'some/newstate'
Inigo

2
@golfadas가 제안한 URL 생성과 결합하면 승자가 있습니다!
crowmagnumb

63

사용하는 location.go(url)것이 방법이지만 url을 하드 코딩하는 대신을 사용하여 생성하는 것이 router.createUrlTree()좋습니다.

다음 라우터 호출을 수행하려는 this.router.navigate([{param: 1}], {relativeTo: this.activatedRoute})경우 구성 요소를 다시로드하지 않고 다음과 같이 다시 작성할 수 있습니다.

const url = this.router.createUrlTree([], {relativeTo: this.activatedRoute, queryParams: {param: 1}}).toString()

 this.location.go(url);

9
이 답변이 내 문제를 해결했습니다. 한 가지 질문은 위에서 생성 된 URL에 ";"(세미콜론)으로 구분 된 매개 변수가 있다는 것입니다. 쿼리의 각 매개 변수를 "&"로 구분하려면 어떻게해야합니까?
Amarnath

2
이것은 createUrlTree (commands : any [], navigationExtras ?: NavigationExtras)의 선언입니다. commads가 아닌 navigationExtras에 위치한 queryParams를 사용해야합니다. createUrlTree ([], {relativeTo : this.activatedRoute, queryParams : {param : 1}})
kit

@kit이 말한 내용을 명확히하기 위해 다음과 같이하십시오.this.router.createUrlTree([], {relativeTo: this.activatedRoute, queryParams: {param: 1}}).toString()
bluegrounds

12

이 질문을 찾는 나 같은 사람에게는 다음이 유용 할 수 있습니다.

비슷한 문제가 있었고 처음에는 여기에 다른 답변에서 제안한대로 location.go 및 location.replaceState를 사용해 보았습니다. 그러나 탐색이 현재 경로에 상대적이고 현재 경로가 location.go 또는 location.replaceState에 의해 업데이트되지 않았기 때문에 앱의 다른 페이지로 이동해야 할 때 문제가 발생했습니다 (라우터는 아무것도 알지 못함). URL에 대한 작업)

본질적으로 나는 경로 매개 변수가 변경되었을 때 페이지 / 구성 요소를 다시로드하지 않고 내부적으로 경로 상태를 업데이트하는 솔루션이 필요했습니다.

결국 쿼리 매개 변수를 사용하게되었습니다. https://angular-2-training-book.rangle.io/handout/routing/query_params.html 에서 자세한 내용을 확인할 수 있습니다.

따라서 주문을 저장하고 주문 ID를 가져와야하는 경우 아래와 같이 페이지 URL을 업데이트 할 수 있습니다. 지도에서 중심 위치 및 관련 데이터를 업데이트하는 것은 유사합니다.

// let's say we're saving an order. Initally the URL is just blah/orders
save(orderId) {
    // [Here we would call back-end to save the order in the database]

    this.router.navigate(['orders'], { queryParams: { id: orderId } });
    // now the URL is blah/orders?id:1234. We don't reload the orders
    // page or component so get desired behaviour of not seeing any 
    // flickers or resetting the page.
}

다음과 같이 ngOnInit 메서드 내에서 추적합니다.

ngOnInit() {
    this.orderId = this.route
        .queryParamMap
        .map(params => params.get('id') || null);
    // orderID is up-to-date with what is saved in database now, or if
    // nothing is saved and hence no id query paramter the orderId variable
    // is simply null.
    // [You can load the order here from its ID if this suits your design]
}

새로운 (저장되지 않은) 주문으로 주문 페이지로 직접 이동해야하는 경우 다음을 수행 할 수 있습니다.

this.router.navigate(['orders']);

또는 기존 (저장된) 주문에 대한 주문 페이지로 직접 이동해야하는 경우 다음을 수행 할 수 있습니다.

this.router.navigate(['orders'], { queryParams: { id: '1234' } });

10

angular2의 RCx 릴리스에서이 작업을 수행하는 데 큰 문제가있었습니다. Location 패키지가 이동되었으며 constructor () 내부에서 location.go () 실행이 작동하지 않습니다. 수명주기에서 ngOnInit () 이상이어야합니다. 다음은 몇 가지 예제 코드입니다.

import {OnInit} from '@angular/core';
import {Location} from '@angular/common';

@Component({
  selector: 'example-component',
  templateUrl: 'xxx.html'
})
export class ExampleComponent implements OnInit
{
  constructor( private location: Location )
  {}

  ngOnInit()
  {    
    this.location.go( '/example;example_param=917' );
  }
}

문제에 대한 각 리소스는 다음과 같습니다. https://angular.io/docs/ts/latest/api/common/index/Location-class.html https://angular.io/docs/ts/latest/api/ common / index / LocationStrategy-class.html


7

나는 이것을 얻기 위해이 방법을 사용한다.

const queryParamsObj = {foo: 1, bar: 2, andThis: 'text'};

this.location.replaceState(
  this.router.createUrlTree(
    [this.locationStrategy.path().split('?')[0]], // Get uri
    {queryParams: queryParamsObj} // Pass all parameters inside queryParamsObj
  ).toString()
);

-- 편집하다 --

이에 대한 정보를 더 추가해야한다고 생각합니다.

this.location.replaceState()응용 프로그램의 라우터 를 사용하는 경우 업데이트되지 않으므로 나중에 라우터 정보를 사용하면 브라우저에서 이와 동일하지 않습니다. 예를 들어을 사용 localizeService하여 언어를 변경하는 경우 언어를 변경 한 후 응용 프로그램을 this.location.replaceState().

이 동작을 원하지 않는 경우 다음과 같이 URL 업데이트에 대해 다른 방법을 선택할 수 있습니다.

this.router.navigate(
  [this.locationStrategy.path().split('?')[0]],
  {queryParams: queryParamsObj}
);

이 옵션에서는 브라우저도 새로 고침되지 않지만 URL변경 사항도 Router애플리케이션에 삽입되므로 언어를 전환 할 때 this.location.replaceState().

물론 필요에 따라 방법을 선택할 수 있습니다. 첫 번째는 URL브라우저 변경보다 애플리케이션을 더 많이 사용하지 않기 때문에 더 가볍습니다 .


3

저에게는 실제로 Angular 4.4.5와 둘 다 혼합되었습니다.

router.navigate를 사용하면 realtiveTo : activateRoute 부분을 존중하지 않아 내 URL이 계속 파괴되었습니다.

나는 끝났다 :

this._location.go(this._router.createUrlTree([this._router.url], { queryParams: { profile: value.id } }).toString())

3

URL을 변경하는 동안 queryParamsHandling : 'merge'속성을 사용하십시오.

this.router.navigate([], {
        queryParams: this.queryParams,
        queryParamsHandling: 'merge',
        replaceUrl: true,
});

3
이로 인해 현재 라우팅 된 구성 요소가 다시로드됩니다
btx
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.