Angular:如何在不更改路线的情况下更新Queryparams

发布于 2025-01-24 09:15:35 字数 282 浏览 0 评论 0原文

我正在尝试从组件中更新(添加,删除)Queryparams。在AngularJS中,过去可能是可能的:

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

我有一个带有用户可以过滤,订购等列表的应用URL或与其他人共享。

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

这对新路由器可行吗?

I am trying to update (add, remove) queryParams from a component. In angularJS, it used to be possible thanks to :

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

I have an app with a list that the user can filter, order, etc and I would like to set in the queryParams of the url all the filters activated so he can copy/paste the url or share it with someone else.

However, I don't want my page to be reloaded each time a filter is selected.

Is this doable with the new router?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

太阳公公是暖光 2025-01-31 09:15:35

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

类似:

// In your .component.ts
import { ActivatedRoute, Router } from '@angular/router';

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

public myMethodChangingQueryParams() {
  const queryParams: Params = { myParam: 'myNewValue' };

  this.router.navigate(
    [], 
    {
      relativeTo: this.activatedRoute,
      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中删除参数。

You can navigate to the current route with new query params, which will not reload your page, but will update query params.

Something like :

// In your .component.ts
import { ActivatedRoute, Router } from '@angular/router';

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

public myMethodChangingQueryParams() {
  const queryParams: Params = { myParam: 'myNewValue' };

  this.router.navigate(
    [], 
    {
      relativeTo: this.activatedRoute,
      queryParams, 
      queryParamsHandling: 'merge', // remove to replace all query params by provided
    }
  );
}

Note, that whereas it won't reload the page, it will push a new entry to the browser's history. If you want to replace it in the history instead of adding new value there, you could use { queryParams: queryParams, replaceUrl: true }.

EDIT:
As already pointed out in the comments, [] and the relativeTo property was missing in my original example, so it could have changed the route as well, not just query params. The proper this.router.navigate usage will be in this case:

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

Setting the new parameter value to null will remove the param from the URL.

八巷 2025-01-31 09:15:35

@radosławRoszkowiak的答案几乎是正确的,除了relativeto:this.route是必需的:

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

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

@Radosław Roszkowiak's answer is almost right except that relativeTo: this.route is required as below:

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

changeQuery() {
    this.router.navigate(['.'], { relativeTo: this.route, queryParams: { ... }});
}
迷你仙 2025-01-31 09:15:35

在Angular 5中,您可以轻松获取并修改 urltree 通过解析当前URL。这将包括查询参数和片段。

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

  this.router.navigateByUrl(urlTree); 

修改查询参数的“正确方法”可能是
createurltree 像下面一样,在下面可以从当前创建一个新的urltree,同时让我们使用< href =“ https://angular.io/api/router/navigationExtras” rel =“ noreferrer”> 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

In Angular 5 you can easily obtain and modify a copy of the urlTree by parsing the current url. This will include query params and fragments.

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

  this.router.navigateByUrl(urlTree); 

The "correct way" to modify a query parameter is probably with the
createUrlTree like below which creates a new UrlTree from the current while letting us modify it using 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); 
}

In order to remove a query parameter this way you can set it to undefined or null.

拒绝两难 2025-01-31 09:15:35

大多数投票的答案部分对我有用。浏览器URL保持不变,但我的RouterLinkactive在导航后不再工作。

我的解决方案是使用乳液。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中删除所有以前的查询字符串。

The answer with most vote partially worked for me. The browser url stayed the same but my routerLinkActive was not longer working after navigation.

My solution was to use 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());
  }
}

I used HttpParams to build the query string since I was already using it to send information with httpClient. but you can just build it yourself.

and the this._router.url.split("?")[0], is to remove all previous query string from current url.

赠意 2025-01-31 09:15:35

尝试

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

除了单引号外,还适用于相同的路线导航。

Try

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

will work for same route navigation other than single quotes.

孤独岁月 2025-01-31 09:15:35

如果您想更改查询参数而无需更改路由。见下文
示例可能会帮助您:
当前路线是:/search
&amp;目标路由为(没有重新加载页面):/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(['search'']而不是this.router.navigate(['。']

If you want to change query params without change the route. see below
example might help you:
current route is : /search
& Target route is(without reload page) : /search?query=love

    submit(value: string) {
      this.router.navigate( ['.'],  { queryParams: { query: value } })
        .then(_ => this.search(q));
    }
    search(keyword:any) { 
    //do some activity using }

please note : you can use this.router.navigate( ['search'] instead of this.router.navigate( ['.']

陈甜 2025-01-31 09:15:35

我最终将urltreelocation.go

import { Location } from '@angular/common'

constructor(private location: Location){}

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

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

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

I ended up combining urlTree with location.go

import { Location } from '@angular/common'

constructor(private location: Location){}

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

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

Not sure if toString can cause problems, but unfortunately location.go, seems to be string based.

星光不落少年眉 2025-01-31 09:15:35

更好的是 - 只需html:

&lt; a [routerlink] =“ []” [queryparams] =“ {key:'value'}”&gt; QUERY参数link&lt&lt&a&gt;

请注意空的数组而不是仅仅执行routerlink =“”[routerlink] =“''''''

Better yet - just HTML:

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

Note the empty array instead of just doing routerLink="" or [routerLink]="''"

柒夜笙歌凉 2025-01-31 09:15:35

与浏览器的URL相互作用而不是路由时,应使用Angular的位置服务。这就是为什么我们要使用位置服务。

Angulars httppparams 用于创建查询参数。请记住,httpparam是不可变的,这意味着在创建值时必须链接它。

最后,使用this._location.replacestate更改为URL而无需重新加载页面/路由和本机JS location.path.path以获取无参数的URL,以每次重置参数时间。

constructor(
    private _location: Location,
) {}

...

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

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

Angular's Location service should be used when interacting with the browser's URL and not for routing. Thats why we want to use Location service.

Angulars HttpParams are used to create query params. Remember HttpParams are immutable, meaning it has to be chained when creating the values.

At last, using this._location.replaceState to change to URL without reloading the page/route and native js location.path to get the url without params to reset the params every time.

constructor(
    private _location: Location,
) {}

...

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

    this._location.replaceState(
        location.pathname,
        params.toString()
    );
}
梦情居士 2025-01-31 09:15:35

首先,我们需要从Angular Router导入路由器模块并声明其别名名称

import { Router } from '@angular/router'; ---> import
class AbcComponent implements OnInit(){
constructor(
    private router: Router ---> declare alias name
  ) { }
}
  1. 您可以通过使用“ router.navigate”函数更改查询参数并传递查询参数,
this.router.navigate([], { queryParams: {_id: "abc", day: "1", name: "dfd"} });

它将在当前IE激活路线中更新以下ie

  1. groms the以下路线。用_id到ABC页面,一天
    并将其称为查询参数,
this.router.navigate(['/abc'], { 
    queryParams: {_id: "abc", day: "1", name: "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
    }

First, we need to import the router module from angular router and declare its alias name

import { Router } from '@angular/router'; ---> import
class AbcComponent implements OnInit(){
constructor(
    private router: Router ---> declare alias name
  ) { }
}
  1. You can change query params by using "router.navigate" function and pass the query parameters
this.router.navigate([], { queryParams: {_id: "abc", day: "1", name: "dfd"} });

It will update query params in the current i.e activated route

  1. The below will redirect to abc page with _id, day
    and name as query params
this.router.navigate(['/abc'], { 
    queryParams: {_id: "abc", day: "1", name: "dfd"} 
});

It will update query params in the "abc" route along with three query paramters

For fetching query params:-

    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
    }
凉薄对峙 2025-01-31 09:15:35

为了维护路径并仅更改参数,您可以使用此代码:

  constructor(private router: Router)   

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

希望它有帮助!

To maintain the path and only change the parameter, you can use this code:

  constructor(private router: Router)   

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

Hope it helps!

混吃等死 2025-01-31 09:15:35

我有一个有趣的情况,我们只在所有路线上都使用一个组件。这就是路由的样子:

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

因此,基本上,路径//compision>/code>和/pipeline都具有与必须为加载。而且,由于Angular会阻止组件的重新加载,如果它们先前已加载到DOM中,则路由器的导航方法返回了始终以null解决的承诺。

为了避免这种情况,我必须使用 onsameurlnavigation 。通过将此值设置为'reload',我设法将路由器 navigate 与更新的查询字符串参数:

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

I've had an interesting situation where we used only one component for all routes we had. This is what routes looked like:

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

So, basically, paths /, /companies and /pipeline were all having the same component that had to be loaded. And, since Angular prevents reloading of the components if they were previously loaded in the DOM, Router's navigate method returned a Promise that always resolved with null.

To avoid this, I had to use onSameUrlNavigation. By setting this value to 'reload', I managed to make the router navigate to the same URL with the updated query string parameters:

@NgModule({
  imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })],
  exports: [RouterModule]
})
千笙结 2025-01-31 09:15:35

您可以使用[]并在Extras添加参数时导航到同一URL,最后添加repleastUrl:true(替换Angular Doc )以超越最后一个当前的历史。

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

而且,如果您需要在每个导航上进行操作,则可以使用路由器。事件如下。

this.routerSubscription = this.router.events.subscribe((event: Event) => {
  if (event instanceof NavigationEnd) {
    this.router.navigate([], {
     queryParams: newQueryParams,
     queryParamsHandling: 'merge',
     replaceUrl: true
    });
  }
});

you can navigate to the same url using [] and in extras add the params, finally add replaceUrl: true (replaceUrl Angular Doc) to overrride the last current history.

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

and if you need to do on every navigation you can use router.events as follow.

this.routerSubscription = this.router.events.subscribe((event: Event) => {
  if (event instanceof NavigationEnd) {
    this.router.navigate([], {
     queryParams: newQueryParams,
     queryParamsHandling: 'merge',
     replaceUrl: true
    });
  }
});
给妤﹃绝世温柔 2025-01-31 09:15:35

另外,您可以添加行为主题:

refresher$ = new BehaviorSubject(null);

我更改了我的代码:

this.route.queryParamMap.subscribe(some code)

到:

combineLatest([
    this.route.queryParamMap,
    this.refresher$
])
  .pipe(
     map((data) => data[0])
  )
  .subscribe(here is your the same code)

当您需要刷新您的订阅时,您需要致电以下:

this.refresher$.next(null);

也不要忘记将其添加到Ngondestroy中

Also you can add BehaviorSubject like:

refresher$ = new BehaviorSubject(null);

I changed my code from that:

this.route.queryParamMap.subscribe(some code)

to:

combineLatest([
    this.route.queryParamMap,
    this.refresher$
])
  .pipe(
     map((data) => data[0])
  )
  .subscribe(here is your the same code)

And when you need refresh your subscription, you need call this:

this.refresher$.next(null);

Also don't forget add unsubscribe from that to ngOnDestroy

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文