Angular:如何在不更改路由的情况下更新queryParams

时间:2017-04-29 16:33:33

标签: angular query-parameters angular-router

我正在尝试从组件更新(添加,删除)queryParams。在angularJS中,它曾经有可能归功于:

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

我有一个应用程序,其中包含用户可以过滤,订购等的列表,我想在url的queryParams中设置所有已激活的过滤器,这样他就可以复制/粘贴URL或与其他人共享。

但是,每次选择过滤器时,我都不希望重新加载页面

新的路由器可行吗?

10 个答案:

答案 0 :(得分:155)

您可以使用新的查询参数导航到当前路径,这不会重新加载您的页面,但会更新查询参数。

像(在组件中)的东西:

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属性,因此它也可以更改路径,而不仅仅是查询参数。在这种情况下,适当的this.router.navigate用法是:

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

将新参数值设置为null将从URL中删除该参数。

答案 1 :(得分:13)

@RadosławRoszkowiak的答案几乎是正确的,但需要relativeTo: this.route,如下所示:

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

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

答案 2 :(得分:9)

在Angular 5中,您可以通过解析当前网址轻松获取和修改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); 
}

要以这种方式删除查询参数,您可以将其设置为undefinednull

答案 3 :(得分:4)

如果要更改查询参数而不更改路径。见下文 示例可能会帮助您: 当前路线是: /搜索 &安培;目标路线是(没有重新加载页面): / 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(['。& #39]

答案 4 :(得分:2)

获得最多投票的答案部分对我有用。浏览器网址保持不变,但导航后我的routerLinkActive不再起作用。

我的解决方案是使用lotation.go:

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

我使用HttpParams构建查询字符串,因为我已经在使用它与httpClient发送信息。但是您可以自己构建。

this._router.url.split("?")[0]是要从当前网址中删除所有以前的查询字符串。

答案 5 :(得分:1)

尝试

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

将用于除单引号之外的相同路线导航。

答案 6 :(得分: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,day重定向到abc页面 并命名为查询参数

    this.router.navigate(['/ abc'],{queryParams:{_id:“ abc”,day:“ 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
    }

答案 7 :(得分:0)

我最终将urlTreelocation.go组合在一起

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

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

不确定toString是否会引起问题,但不幸的是,location.go似乎是基于字符串的。

答案 8 :(得分:0)

更好-仅HTML:

<a [routerLink]="[]" [queryParams]="{key: 'value'}">Your Query Params Link</a>

注意空数组,而不是只做routerLink=""[routerLink]="''"

答案 9 :(得分:0)

Angular 的位置服务应该在与浏览器的 URL 交互时使用,而不是用于路由。这就是我们要使用 Location 服务的原因。

Angulars HttpParams 用于创建查询参数。请记住 HttpParams 是不可变的,这意味着在创建值时必须将其链接起来。

最后,使用this._location.replaceState更改为URL而不重新加载页面/路由和原生jslocation.path获取没有params的url每次都重置params。

constructor(
    private _location: Location,
) {}

...

updateURLWithNewParamsWithoutReloading() {
    const params = new HttpParams().appendAll({
        price: 100,
        product: 'bag'
    });

    this._location.replaceState(
        location.pathname,
        params.toString()
    );
}