Angular: как обновить queryParams без изменения маршрута

Я пытаюсь обновить (добавить, удалить) queryParams из компонента. В angularJS это было возможно благодаря:

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

У меня есть приложение со списком, который пользователь может фильтровать, заказывать и т.д., и я хотел бы задать в параметрах queryParams URL все активированные фильтры, чтобы он мог скопировать/вставить URL-адрес или поделиться им с кем-то другим.

Однако я не хочу, чтобы моя страница была перезагружена каждый раз, когда выбран фильтр.

Возможно ли это с новым маршрутизатором?

Ответ 1

Вы можете перейти к текущему маршруту с новыми параметрами запроса, которые не будут перезагружать вашу страницу, но обновят параметры запроса.

Что-то вроде (в компоненте):

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.

Ответ 2

@Ответ Radosław Roszkowiak почти прав, за исключением того, что relativeTo: this.route требуется, как показано ниже:

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

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

Ответ 3

В Angular 5 вы можете легко получить и изменить копию urlTree, анализируя текущий URL. Это будет включать в себя параметры запроса и фрагменты.

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

Чтобы удалить параметр запроса таким образом, вы можете установить его как undefined или null.

Ответ 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(['search'] вместо this.router.navigate(['.']

Ответ 5

Пытаться

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

будет работать для навигации по тому же маршруту, кроме одинарных кавычек.

Ответ 6

Ответ с большинством голосов частично сработал для меня. URL браузера остался прежним, но мой 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], чтобы удалить всю предыдущую строку запроса из текущего URL.

Ответ 7

Во-первых, нам нужно импортировать модуль маршрутизатора из углового маршрутизатора и объявить его псевдоним

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. Ниже будет перенаправлен на страницу abc с _id, день и имя в качестве параметров запроса

    this.router.navigate(['/abc'], {queryParams: {_id: "abc", день: "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
    }

Ответ 8

Я думаю, @Dummy обращается к тому, как вы получаете параметры, но я не думаю, что это обрабатывает настройку. Вы можете использовать location.replaceState.

import {Location} from '@angular/common';  ...

constructor(private location: Location ...

setFilter() {
   let params = '?item1=thing1&item2=thing2';
   this.location.replaceState(params);
}