我试图更新(添加,删除)queryParams从一个组件。在angularJS中,它曾经是可能的,这要归功于:

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

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

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

新路由器能做到吗?


当前回答

大多数人投票的答案在一定程度上对我有用。浏览器的url保持不变,但我的routerLinkActive在导航后不再工作。

我的解决方案是使用lotit .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],是从当前url中删除所有之前的查询字符串。

其他回答

更好的是-只有HTML:

<a [routerLink]="

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

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

类似于(在组件中):

import {ActivatedRoute, Router} from '@angular/router';
constructor(
    private router: Router,
    private activatedRoute: ActivatedRoute,
) { }

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中删除参数。

在Angular 5中,你可以通过解析当前url来轻松获取和修改urlTree的副本。这将包括查询参数和片段。

  let urlTree = this.router.parseUrl(this.router.url);
  urlTree.queryParams['newParamKey'] = 'newValue';

  this.router.navigateByUrl(urlTree); 

修改查询参数的“正确方法”可能是使用 创建一个新的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); 
}

为了以这种方式删除查询参数,可以将其设置为undefined或null。

我遇到过一个有趣的情况,我们对所有的路线只使用了一个组件。这是路线的样子:

const routes: Routes = [
  {
    path: '',
    component: HomeComponent,
    children: [
      { path: 'companies', component: HomeComponent },
      { path: 'pipeline', component: HomeComponent },
      // ...
    ]
  },
  // ...
];

基本上,paths / /companies和/pipeline都有相同的组件需要加载。而且,由于Angular会阻止组件在DOM中之前被加载,所以Router的navigate方法会返回一个总是以null解析的Promise。

为了避免这种情况,我不得不使用onSameUrlNavigation。通过设置这个值为'reload',我设法使路由器导航到相同的URL与更新的查询字符串参数:

@NgModule({
  imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],
  exports: [RouterModule]
})

大多数人投票的答案在一定程度上对我有用。浏览器的url保持不变,但我的routerLinkActive在导航后不再工作。

我的解决方案是使用lotit .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],是从当前url中删除所有之前的查询字符串。