Получить текущий маршрут без параметров

Мне нужно получить текущий маршрут без параметров в Angular 2, я нашел способ получить текущий маршрут с параметрами следующим образом:

 this.router.url

а затем разделите его:

 this.router.url.split(';')[0]

Но это выглядит как обходной путь, я думаю, должен быть лучший способ?


person Sabri Aziri    schedule 28.02.2017    source источник
comment
this.dom.URL.split('?')[0] -> где dom является экземпляром DOCUMENT   -  person Pardeep Jain    schedule 07.08.2019
comment
Угловым способом было бы импортировать Router из @angular/router, а затем просто использовать this.router.parseUrl(this.router.url).root.children.primary.segments. Если цель состояла в том, чтобы как можно больше разработчиков предпочли Vue или React Angular, то это очень хорошо выполненная работа. Снимаю шляпу, архитекторы Angular! И нет, предоставления подписки недостаточно. Что делать, если я хочу получить активированные параметры маршрута в компоненте, созданном после изменения маршрута (т.е. в модальном)? Вам необходимо предоставить подписки, а также методы для получения текущего значения. Сделайте его удобным для детей! Это ваша цель!   -  person tao    schedule 10.10.2020


Ответы (12)


parseTree from Router помогает получать сегменты без каких-либо знаний о структуре URL.

import { Router } from '@angular/router';
...
constructor(private router: Router) {}
...
const urlTree = this.router.parseUrl(url);
const urlWithoutParams = urlTree.root.children['primary'].segments.map(it => it.path).join('/');

Начните отсюда. Если у вас есть дополнительные розетки, отрегулируйте их по мере необходимости.

person André Werlang    schedule 08.09.2017
comment
Если url равно /, основных дочерних элементов нет. Итак, urlWithoutParam должно быть /, если urlTree.root.children.primary равно undefined. - person Guido Flohr; 27.01.2020

Чтобы получить текущий маршрут без параметров запроса, вы можете использовать одну строку ниже:

this.router.url.split('?')[0] 
person Yanusha Cooray    schedule 17.10.2018
comment
Чем ваш подход отличается от того, который упоминается в его вопросе (this.router.url.split(';')[0])? - person Alexander Abakumov; 18.10.2018

Для меня это самое чистое решение, которое мне удалось сделать. Я надеюсь, что это помогает

import { Router } from '@angular/router';

constructor(private router: Router){}

getUrlWithoutParams(){
   let urlTree = this.router.parseUrl(this.router.url);
   urlTree.queryParams = {}; 
   return urlTree.toString();
}
person Andreas Hadjithoma    schedule 05.06.2020
comment
нет необходимости использовать здесь let, можно использовать const - person dude; 28.11.2020
comment
хорошая стратегия, я пробовал некоторые варианты с urlTree... единственное, что я думаю, что это усложняет тестирование? - person ahong; 21.01.2021
comment
@ahong, я думаю, это может быть сложнее, но я думаю, что методы разделения, упомянутые в других ответах, самые сложные, когда дело доходит до тестирования. - person Andreas Hadjithoma; 21.01.2021
comment
мы используем макет маршрутизатора для наших тестов, поэтому метод parseUrl недоступен. Похоже, кто-то рекомендовал RouterTestingModule stackoverflow.com/a/59855413/2088345. Это было просто немного больше настроено. - person ahong; 21.01.2021

Если вы используете webpack, вы можете использовать модуль url polyfill, который поставляется вместе с модулем Angular Router.

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import * as url from 'url'

@Component({
  selector: 'app-component',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  public constructor(public readonly router: Router) {}

  public ngOnInit() {
    const urlInfo = url.parse(this.router.url)
    console.log(urlInfo.pathname)
  }
}
person Get Off My Lawn    schedule 31.07.2020
comment
какие-либо недостатки использования полифилла webpack? Просто слишком связано с веб-пакетом или это довольно стандартно? - person ahong; 21.01.2021
comment
устарело — начиная с версии 11.0.0 — используйте API URL WHATWG nodejs.org/api/url.html# url_url_pathname - person Eric Belisle Giddings; 29.07.2021

Короткий и простой чистый js.

location.pathname
person אברימי פרידמן    schedule 25.09.2020
comment
РОФЛ. Интересно, может ли кто-нибудь подсказать, почему бы просто не использовать это чистое и приятное решение по сравнению с угловыми решениями. - person Harald; 30.07.2021

Собственный javascript будет работать, чтобы разделить URL-адрес на логические части. Проверьте объект "location" (или window.location). Например, используя местоположение по URL-адресу https://example.com/pathname1/pathname2?queryParam1=1&queryParam2=2 дает

location.origin === 'https://example.com/pathname1/pathname2'
location.href === 'https://example.com/pathname1/pathname2?queryParam1=1&queryParam2=2'
location.pathname === '/pathname1/pathname2'
location.search === '?queryParam1=1&queryParam2=2'
person Cameron Burger    schedule 10.05.2019

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

Я обнаружил, что activatedRoute.routeConfig.path был отличным вариантом, и мне было легко увидеть, какой маршрут использовался.

constructor(private activatedRoute: ActivatedRoute) {}
ngOnInit() {
  if (this.activatedRoute.routeConfig.path === 'heroes/:id')
person Des Horsley    schedule 03.05.2019

это может помочь вам:

  1. Импортировать маршрутизатор:

    import { Router } from '@angular/router';
    
  2. Подпись в конструкторе:

    constructor(private _router: Router) {}
    
  3. Проверьте свойство событий _router:

    this._router.events
        .subscribe(
            (url:any) => {
                let _ruta = "";
                url.url.split("/").forEach(element => {
                    if(element!=="" && _ruta==="")
                        _ruta="/"+element;
                    });
                console.log("route: "+_ruta); //<<<---- Root path
                console.log("to URL:"+url.url); //<<<---- Destination URL 
                console.log("from URL:"+this._router.url);//<<<---- Current URL
            }); 
    
person eberlast    schedule 01.05.2017

Чтобы получить текущий маршрут без параметров запроса, вы можете использовать одну строку ниже:

this.url = this.url.substr(0, this.url.lastIndexOf("?"));
person Temo Kiknadze    schedule 12.11.2020

В моем случае мне нужно было сравнить предыдущий маршрут и новый маршрут при изменении только :id в URL через router.navigate. Поскольку мне нужен был путь без разных идентификаторов, я получил исходный путь маршрута:

/* 
    Routes = [
        { path: 'main/details/:id', component: DetailComponent }
    ]

    previousRoute = '/main/details/1'
    newRoute      = '/main/details/2'
*/

this.routeSubscription = this.router.events.filter((event) => event instanceof ResolveStart)
                                           .pairwise() // returns previous and current events
                                           .subscribe((ev: [ResolveStart, ResolveStart]) => {

    let sameRoute = ev[0].state.root.firstChild.routeConfig.path == ev[1].state.root.firstChild.routeConfig.path ?
                       ev[0].state.root.firstChild.routeConfig.path : undefiend;
    if (sameRoute) {
        // Same routes, probably different ids 
        console.log(sameRoute) // gives 'main/details/:id'
    } else {
        // Different routes
    }
});
person StinkyCat    schedule 14.12.2017
comment
У меня это не сработало, у мероприятия не было государственной собственности - person Zymotik; 02.01.2018

Я использую locationStrategy, как и в ответе на принятие, но с методом .split(). LocationStrategy отлично работает в Angular 4 и Angular 5;

import {LocationStrategy} from '@angular/common';

export class MyService {
    constructor(private locationStrategy: LocationStrategy) {
    }

    public getUrl(filters: FilterConfig[]): void {
        const url = this.locationStrategy.path();
        const urlArray = url.split('?');

        return urlArray[0];
    }
}

Еще одна вещь, о которой вы должны помнить, это убедиться, что ваш <router-outlet> правильно инициализирован, прежде чем пытаться получить locationStrategy.path(). Если <router-outlet> не инициализирован, никакие службы Angular не могут правильно вернуть URL-адрес и параметры запроса.

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

this.router.events.subscribe((evt) => {
...
}

Но в этом случае вы запускаете свою функцию при каждом изменении маршрутизатора, поэтому вам нужно защитить этот случай, если это нежелательно.

person kris_IV    schedule 31.01.2018

Ни один из них не работал для меня.

Есть много подходов к этому, но в этом случае была установлена ​​защита, чтобы пользователи не переходили по определенным URL-адресам. Это работало нормально, за исключением случаев, когда URL-адрес имел параметры, поскольку переданный URL-адрес всегда содержал все параметры.

E.G: myPage/param1/param2

Or: myPage?param1=1&param2=2

В этом случае я бы хотел просто myPage.

Я закодировал ниже, мне это не нравится, я уверен, что это можно улучшить, но пока не нашел ничего, что работает:

    let url: string = state.url;
    let urlParams: string[];

    if (url.includes("?")) {
        url = url.substr(0, url.indexOf('?'));
    } else {
        urlParams = route.url.toString().split(';')[0].split(',');

        if (urlParams.length > 1) {
            urlParams.shift(); // Remove first element which is page name

            // Get entire splitting on each param
            let fullUrlSegments: string[] = state.url.split('/');
            // Remove number of params from full URL
            fullUrlSegments = fullUrlSegments.slice(0, fullUrlSegments.length - urlParams.length);

            url = fullUrlSegments.join('/');
        }
    }

    alert(url);

state.url исходит из реализации CanActivate (или внедрения Router).

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) Observable<boolean> { ... }
person Ricky    schedule 27.03.2018