Javascript 在 Angular 2 中无需重新加载即可更改路由参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35618463/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:00:59  来源:igfitidea点击:

Change route params without reloading in Angular 2

javascriptangularroutesangular2-routing

提问by Marcos Basualdo

I'm making a real estate website using Angular 2, Google Maps, etc. and when a user changes the center of the map I perform a search to the API indicating the current position of the map as well as the radius. The thing is, I want to reflect those values in the url without reloading the entire page. Is that possible? I've found some solutions using AngularJS 1.x but nothing about Angular 2.

我正在使用 Angular 2、Google 地图等制作房地产网站,当用户更改地图中心时,我会搜索 API,指示地图的当前位置以及半径。问题是,我想在不重新加载整个页面的情况下在 url 中反映这些值。那可能吗?我找到了一些使用 AngularJS 1.x 的解决方案,但对 Angular 2 一无所知。

采纳答案by Pankaj Parkar

You could use location.go(url)which will basically change your url, without change in route of application.

您可以使用location.go(url)which 基本上会改变您的网址,而不会改变应用程序的路线。

NOTEthis could cause other effect like redirect to child route from the current route.

注意这可能会导致其他效果,例如从当前路由重定向到子路由。

Related questionwhich describes location.gowill not intimate to Routerto happen changes.

描述location.go不会Router发生变化的相关问题

回答by tjuzbumz

As of RC6 you can do the following to change URL without change state and thereby keeping your route history

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

回答by golfadas

Using location.go(url)is the way to go, but instead of hardcoding the url , consider generating it using router.createUrlTree().

使用location.go(url)是可行的方法,但不要对 url 进行硬编码,而是考虑使用router.createUrlTree().

Given that you want to do the following router call: this.router.navigate([{param: 1}], {relativeTo: this.activatedRoute})but without reloading the component, it can be rewritten as:

鉴于您想要执行以下路由调用:this.router.navigate([{param: 1}], {relativeTo: this.activatedRoute})但无需重新加载组件,它可以重写为:

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

 this.location.go(url);

回答by Luke Dupin

I had major trouble getting this to work in RCx releases of angular2. The Location package has moved, and running location.go() inside constructor() wont work. It needs to be ngOnInit() or later in the lifecycle. Here is some example code:

我很难让它在 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' );
  }
}

Here are the angular resources on the matter: https://angular.io/docs/ts/latest/api/common/index/Location-class.htmlhttps://angular.io/docs/ts/latest/api/common/index/LocationStrategy-class.html

以下是有关此事的角度资源:https: //angular.io/docs/ts/latest/api/common/index/Location-class.html https://angular.io/docs/ts/latest/api/通用/索引/LocationStrategy-class.html

回答by TornadoAli

For anyone like me finding this question the following might be useful.

对于像我这样发现这个问题的人,以下内容可能有用。

I had a similar problem and initially tried using location.go and location.replaceState as suggested in other answers here. However I ran into problems when I had to navigate to another page on the app because the navigation was relative to the current route and the current route wasn't being updated by location.go or location.replaceState (the router doesn't know anything about what these do to the URL)

我遇到了类似的问题,最初尝试使用 location.go 和 location.replaceState,如此处其他答案中的建议。但是,当我不得不导航到应用程序上的另一个页面时遇到了问题,因为导航是相对于当前路线的,并且当前路线没有被 location.go 或 location.replaceState 更新(路由器不知道任何事情关于这些对 URL 的作用)

In essence I needed a solution that DIDN'T reload the page/component when the route parameter changed but DID update the route state internally.

本质上,我需要一个解决方案,当路由参数更改但 DID 在内部更新路由状态时,不会重新加载页面/组件。

I ended up using query parameters. You can find more about it here: https://angular-2-training-book.rangle.io/handout/routing/query_params.html

我最终使用了查询参数。您可以在此处找到更多相关信息:https: //angular-2-training-book.rangle.io/handout/routing/query_params.html

So if you need to do something like save an order and get an order ID you can update your page URL like shown below. Updating a centre location and related data on a map would be similar

因此,如果您需要执行诸如保存订单并获取订单 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.
}

and you keep track of it within the ngOnInit method like:

并且您在 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]
}

If you need to go direct to the order page with a new (unsaved) order you can do:

如果您需要使用新的(未保存的)订单直接进入订单页面,您可以执行以下操作:

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

Or if you need to go direct to the order page for an existing (saved) order you can do:

或者,如果您需要直接转到现有(已保存)订单的订单页面,您可以执行以下操作:

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

回答by kris_IV

I use this way to get it:

我用这种方式来获取它:

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

-- EDIT --

- 编辑 -

I think that I should add some more informations for this.

我认为我应该为此添加更多信息。

If you use this.location.replaceState()router of your application is not updated, so if you use router information later it's not equal for this in your browser. For example if you use localizeServiceto change language, after switch language your application back to last URL where you was before change it with this.location.replaceState().

如果您使用this.location.replaceState()路由器的应用程序未更新,因此如果您稍后使用路由器信息,则在浏览器中不等于此信息。例如,如果您使用localizeService更改语言,则在将语言切换回您的应用程序后,您使用this.location.replaceState().

If you don't want this behaviour you can chose different method for update URL, like:

如果您不想要这种行为,您可以为更新 URL 选择不同的方法,例如:

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

In this option your browser also doesn't refresh but your URLchange is also injected into Routerof your application, so when you switch language you don't have problem like in this.location.replaceState().

在此选项中,您的浏览器也不会刷新,但您的URL更改也会注入到Router您的应用程序中,因此当您切换语言时,您不会遇到this.location.replaceState().

Of course you can choose method for your needs. The first is more lighter because you don't engage your application more than change URLin browser.

当然,您可以根据需要选择方法。第一个更轻量,因为您不会更多地参与应用程序,而不是更改URL浏览器。

回答by Rajeev Raushan Prasad

Use attribute queryParamsHandling: 'merge' while changing the url.

在更改 url 时使用属性 queryParamsHandling: 'merge'。

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

回答by Patrick P.

For me it was actually a mix of both with Angular 4.4.5.

对我来说,它实际上是两者与 Angular 4.4.5 的混合。

Using router.navigate kept destroying my url by not respecting the realtiveTo: activatedRoute part.

使用 router.navigate 通过不遵守 realtiveTo:activationRoute 部分来不断破坏我的 url。

I've ended up with:

我结束了:

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