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

IT技术 javascript angular routes angular2-routing
2021-01-14 21:37:49

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

6个回答

从 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'
2021-03-22 21:37:49
将其与@golfadas 建议的 url 创建结合起来,我们就有了赢家!
2021-04-10 21:37:49

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

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

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

import { Location } from '@angular/common'; 在 Angular 4
2021-03-25 21:37:49
我的路线有一个名为“搜索”的参数,其中接收搜索字段的序列化版本,当列表状态第一次加载时,我只使用 this._routeParams.get('search') 读取这些参数,反序列化过滤器并执行搜索。如果用户通过使用地图或搜索方面更改搜索字段,我只需使用路由器 var 指令 = this._router.generate(['Listing',{search: serializedFields}] 的方法 generate 构造正确的 url ) 然后使用 this._location.go(instruction.urlPath) 改变 url 而不重新加载状态。
2021-03-27 21:37:49
@AdrianE 问题很可能是您在输入location.go()时输入了this.location.go(). 当您发出 时this.,您会调用 Typescript 的位置接口。
2021-03-28 21:37:49
如果其他人想知道: import { Location } from 'angular2/platform/common';
2021-04-08 21:37:49
你是否喜欢构造函数 constructor(private location: Location){ }
2021-04-10 21:37:49

使用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);
这个答案解决了我的问题。一个问题,上面生成的 url 具有由“;”(分号)分隔的参数。我们应该怎么做才能用“&”分隔查询中的每个参数?
2021-03-17 21:37:49
这是 createUrlTree(commands: any[], navigationExtras?: NavigationExtras) 的声明。您必须使用 queryParams 定位 navigationExtras 而不是命令。createUrlTree([], {relativeTo: this.activatedRoute, queryParams: {param: 1} })
2021-03-17 21:37:49
只是为了澄清@kit 所说的内容,请执行以下操作: this.router.createUrlTree([], {relativeTo: this.activatedRoute, queryParams: {param: 1}}).toString()
2021-03-19 21:37:49
这是一个好主意,但是location.gothis.activatedRoute 不会改变,因此您还将向旧路由添加参数……
2021-03-26 21:37:49

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

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

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

我最终使用了查询参数。您可以在此处找到更多相关信息: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' } });
事实上,这正确地更新了路线(从 Angular 的角度来看)并没有在 重建组件'orders',这正是我想要的。
2021-04-02 21:37:49

我很难让它在 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/通用/索引/LocationStrategy-class.html