Angular 2'de yeniden yüklemeden rota parametrelerini değiştirin


114

Angular 2, Google Maps, vb. Kullanarak bir emlak web sitesi yapıyorum ve bir kullanıcı haritanın merkezini değiştirdiğinde, haritanın mevcut konumunu ve yarıçapı gösteren API'de bir arama gerçekleştiriyorum. Mesele şu ki, bu değerleri tüm sayfayı yeniden yüklemeden url'de yansıtmak istiyorum. Mümkün mü? AngularJS 1.x kullanarak bazı çözümler buldum, ancak Angular 2 hakkında hiçbir şey bulamadım.


[routerLink] = "['/ route', {param1: value1}] kullanırsanız, sayfayı yeniden yüklemeyeceğini düşünüyorum
Araç Seti

ancak başka bir sorgu parametresini nasıl ekleyebilirim?
Araç Seti

2
☝️ sayfanın yeniden yüklenmesine neden olur
LifterCoder

Sitenizi SEO uyumlu hale getirmek için SSR kullanıyorsanız, bunun tartışmalı bir problem olduğunu unutmayın.
Jonathan

@Jonathan, değil mi? Statik sayfa oluşturulduktan sonra yönlendirmeyi Angular devraldığından, SSR kullanırken bile bunun hala geçerli bir soru olduğunu düşünürdüm.
adam0101

Yanıtlar:


92

location.go(url)Uygulama yolunda değişiklik yapmadan temelde URL'nizi değiştirecek olanı kullanabilirsiniz .

NOT bu, geçerli rotadan alt rotaya yeniden yönlendirme gibi başka etkilere neden olabilir.

İlgili soru açıklarlocation.goiçin intimate olmazRouterdeğişiklikleri gerçekleşmesi.


2
Rotamda arama alanlarının serileştirilmiş bir sürümünü alan 'arama' adlı bir parametre var, listeleme durumu ilk kez yüklendiğinde bu parametreleri yalnızca this._routeParams.get ('arama') kullanarak okudum, filtrelerin serisini kaldır ve aramayı gerçekleştirin. Kullanıcı arama alanlarını haritayı veya arama yönlerini kullanarak değiştirirse, yönlendiricinin oluşturduğu yöntemi kullanarak doğru url'yi oluştururum var talimat = this._router.generate (['Listing', {search: serializedFields}] ) ve sonra url'yi durumu yeniden yüklemeden değiştirmek için this._location.go (talimat.urlPath) kullanarak.
Marcos Basualdo

20
Merak eden başka biri varsa: "angular2 / platform / common" konumundan {Location} öğesini içe aktarın;
Kesarion

18
import { Location } from '@angular/common';in Angular 4
tehCivilian

2
Yapımcılığa karar verdiniz miconstructor(private location: Location){ }
Pankaj Parkar

2
Sorun yazdığınız çoğu muhtemelen @AdrianE location.go()Yazdığınız gerekirken this.location.go(). Eğer yayarlar zaman this., sen typescript konumu-arayüzünü diyoruz.
georg-un

94

RC6'dan itibaren, URL'yi değiştirmeden değiştirmek ve böylece rota geçmişinizi saklamak için aşağıdakileri yapabilirsiniz.

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

Bu benim için çalışmıyor. Rotayı yüklemeye çalışır. Konsol hatası:Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'some/newstate'
Inigo

2
Bunu @ golfadas tarafından önerildiği gibi url oluşturma ile birleştirin ve bir kazananımız var!
crowmagnumb

63

Kullanmak location.go(url)gitmenin yoludur, ancak url'yi kodlamak yerine kullanarak oluşturmayı düşünün router.createUrlTree().

Aşağıdaki yönlendirici çağrısını yapmak istediğiniz göz önüne alındığında: this.router.navigate([{param: 1}], {relativeTo: this.activatedRoute})ancak bileşeni yeniden yüklemeden, şu şekilde yeniden yazılabilir:

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

 this.location.go(url);

9
Bu cevap sorunumu çözdü. Bir soru, yukarıda üretilen url'de ";" (noktalı virgül) ile ayrılmış parametreler var. Sorgudaki her bir parametreyi "&" ile ayırmak için ne yapmalıyız?
Amarnath

2
bu, createUrlTree'nin beyanıdır (komutlar: any [], navigationExtras ?: NavigationExtras). commads değil, queryParams'da bulunan navigationExtras'ı kullanmanız gerekir. createUrlTree ([], {relativeTo: this.activatedRoute, queryParams: {param: 1}})
kit

: Sadece @kit söylediklerine netleştirmek için, bunuthis.router.createUrlTree([], {relativeTo: this.activatedRoute, queryParams: {param: 1}}).toString()
bluegrounds

12

Benim gibi bu soruyu bulan biri için aşağıdakiler yararlı olabilir.

Benzer bir sorun yaşadım ve ilk olarak location.go ve location.replaceState'i buradaki diğer yanıtlarda önerildiği gibi kullanmayı denedim. Ancak uygulamada başka bir sayfaya gitmem gerektiğinde sorunlarla karşılaştım çünkü navigasyon mevcut rotaya göreydi ve mevcut rota location.go veya location.replaceState ile güncellenmiyordu (yönlendirici hiçbir şey bilmiyor bunların URL'ye ne yaptığı hakkında)

Esasen, rota parametresi değiştiğinde DIDN'T'nin sayfayı / bileşeni yeniden yüklemesini ancak DID'nin rota durumunu dahili olarak güncellemesi gereken bir çözüme ihtiyacım vardı.

Sorgu parametrelerini kullanmayı bıraktım. Bununla ilgili daha fazla bilgiyi burada bulabilirsiniz: https://angular-2-training-book.rangle.io/handout/routing/query_params.html

Dolayısıyla, bir siparişi kaydetmek ve bir sipariş kimliği almak gibi bir şey yapmanız gerekirse, sayfa URL'nizi aşağıda gösterildiği gibi güncelleyebilirsiniz. Bir merkez konumunu ve bir harita üzerindeki ilgili verileri güncellemek benzer olacaktır.

// 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.
}

ve aşağıdaki gibi ngOnInit yöntemi içinde takip edersiniz:

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]
}

Yeni (kaydedilmemiş) bir siparişle doğrudan sipariş sayfasına gitmeniz gerekiyorsa şunları yapabilirsiniz:

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

Veya mevcut (kaydedilmiş) bir sipariş için doğrudan sipariş sayfasına gitmeniz gerekiyorsa şunları yapabilirsiniz:

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

10

Angular2'nin RCx sürümlerinde bunu çalıştırmakta büyük sorun yaşadım. Location paketi taşındı ve constructor () içindeki location.go () işlevini çalıştırmak çalışmayacak. Yaşam döngüsünde ngOnInit () veya daha sonra olması gerekir. İşte bazı örnek kod:

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

Konuyla ilgili açısal kaynaklar şunlardır: https://angular.io/docs/ts/latest/api/common/index/Location-class.html https://angular.io/docs/ts/latest/api/ ortak / index / LocationStrategy-class.html


7

Bunu elde etmek için bu yolu kullanıyorum:

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

-- DÜZENLE --

Bunun için biraz daha bilgi eklemem gerektiğini düşünüyorum.

this.location.replaceState()Uygulamanızın yönlendiricisini kullanırsanız güncellenmez, bu nedenle yönlendirici bilgilerini daha sonra kullanırsanız, tarayıcınızda bununla aynı değildir. Örneğin localizeService, dili değiştirmek için kullanırsanız , dili değiştirdikten sonra uygulamanızı ile değiştirmeden önce bulunduğunuz son URL'ye geri dönün this.location.replaceState().

Bu davranışı istemiyorsanız, güncelleme URL'si için farklı bir yöntem seçebilirsiniz, örneğin:

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

Bu seçenekte tarayıcınız da yenilenmez ancak URLdeğişikliğiniz uygulamanıza da eklenir Router, böylece dili değiştirdiğinizde dilinde olduğu gibi sorun yaşamazsınız this.location.replaceState().

Elbette ihtiyaçlarınız için yöntem seçebilirsiniz. İlki daha hafiftir çünkü uygulamanızı URLtarayıcıdaki değişiklikten daha fazla kullanmazsınız .


3

Benim için aslında Angular 4.4.5 ile ikisinin bir karışımıydı.

Router.navigate kullanımı, realtiveTo: enabledRoute kısmına saygı göstermeyerek url'mi yok etmeye devam etti.

Şununla bitirdim:

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

3

URL'yi değiştirirken queryParamsHandling: 'merge' özelliğini kullanın.

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

3
Bu, halihazırda yönlendirilmiş olan bileşenin yeniden yüklenmesine neden olur
btx
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.