【问题标题】:Get current route without parameters获取不带参数的当前路线
【发布时间】:2017-07-19 04:35:34
【问题描述】:

我需要在 Angular 2 中获取不带参数的当前路线,我找到了一种使用参数获取当前路线的方法,如下所示:

 this.router.url

然后拆分:

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

但这看起来是一种解决方法,我认为应该有更好的方法?

【问题讨论】:

  • this.dom.URL.split('?')[0] -> 其中 dom 是 DOCUMENT 的实例
  • “角度”方式是从@angular/router 导入路由器,然后“简单” 使用this.router.parseUrl(this.router.url).root.children.primary.segments。如果目标是让尽可能多的开发人员更喜欢 Vue 或 React 而不是 Angular,那么这项工作做得非常好。脱帽致敬,Angular 架构师!不,提供订阅是不够的。如果我想在路由更改后创建的组件(即:模态)中获取激活的路由参数怎么办?您需要公开订阅以及获取当前值的方法。让孩子轻松使用!这就是你的目标!

标签: angular url angular2-routing angular2-router


【解决方案1】:

要获取不带查询参数的当前路线,可以使用下面提到的单行:

this.url = this.url.substr(0, this.url.lastIndexOf("?"));

【讨论】:

    【解决方案2】:

    简洁的纯js。

    location.pathname
    

    【讨论】:

    • ROFL。我想知道是否有人可以提供一个提示,与以角度为中心的解决方案相比,为什么不直接使用这种干净而甜蜜的解决方案。
    • @Harald 如果你在使用 Angular 的 SSR 环境中,windowlocation 不可用。
    • 没错。 SSR 使服务器端无法实现,但对于许多其他用例,location.pathname 将是理想的。
    • 它不适用于哈希路由。例如,http://example.com/#/app?x=1
    • 如果使用 Angular API,迁移可能会更容易。我想。
    【解决方案3】:

    我有类似的要求,具体取决于我使用哪条途径来获得我想要不同结果的组件。

    我发现activatedRoute.routeConfig.path 是一个不错的选择,让我可以轻松查看使用了哪条路线。

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

    【讨论】:

    • 对我不起作用。 this.activatedRoute.routeConfig.path 返回一个空白字符串。
    【解决方案4】:

    如果您使用 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)
      }
    }
    

    【讨论】:

    【解决方案5】:

    对我来说,这是我设法做到的最干净的解决方案。希望对你有帮助

    import { Router } from '@angular/router';
    
    constructor(private router: Router){}
    
    getUrlWithoutParams(){
       let urlTree = this.router.parseUrl(this.router.url);
       urlTree.queryParams = {}; 
       return urlTree.toString();
    }
    

    【讨论】:

    • 这里不用let,用const就可以了
    • 不错的策略,我尝试了一些 urlTree 的变体......唯一的问题是我认为它使测试变得更加困难?
    • @ahong 我想这可能会更难,但我认为其他答案中提到的“拆分”方法在测试方面是最难的
    • 我们使用模拟路由器进行测试,因此parseUrl 方法不可用。好像有人推荐了RouterTestingModulestackoverflow.com/a/59855413/2088345。只是设置多了一点。
    【解决方案6】:

    要获取不带查询参数的当前路线,可以使用下面提到的单行:

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

    【讨论】:

    • 您的方法与他的问题 (this.router.url.split(';')[0]) 中提到的 OP 有何不同?
    • 你不应该订阅 observable 吗?
    【解决方案7】:

    本机 javascript 可以将 url 拆分为逻辑部分。查看“位置”(或 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'
    

    【讨论】:

      【解决方案8】:

      这些都不适合我。

      有很多方法可以解决这个问题,但在这种情况下,有一个保护措施可以阻止用户访问特定的 URL。这工作正常,除非 URL 具有参数,因为传递的 URL 始终包含所有参数。

      例如:myPage/param1/param2

      或者: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> { ... }
      

      【讨论】:

        【解决方案9】:

        我在接受答案中使用 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];
            }
        }
        

        您应该携带的另一件事是确保在尝试获取locationStrategy.path() 之前正确初始化您的&lt;router-outlet&gt;。如果&lt;router-outlet&gt; 没有初始化,任何Angular 服务都不能正确返回URL 和查询参数。

        为确保您的位置策略已初始化,您可以使用以下订阅方法:

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

        但在这种情况下,您会在每次路由器更改时触发您的功能,因此如果不需要,您需要保护这种情况。

        【讨论】:

          【解决方案10】:

          在我的例子中,当通过 router.navigate 仅更改 url 上的 :id 时,我需要比较以前的路由和新路由。由于我想要没有不同ID的路径,所以我得到了路由的原始路径:

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

          【讨论】:

          • 这对我不起作用,该事件没有状态属性
          【解决方案11】:

          来自RouterparseTree 有助于在不了解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('/');
          

          从这里开始。如果您有辅助插座,请根据需要进行调整。

          【讨论】:

          • 如果url/,则没有主要的孩子。所以,urlWithoutParam 应该是 / 如果 urlTree.root.children.primaryundefined
          【解决方案12】:

          这可以帮助你:

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

          【讨论】:

            猜你喜欢
            • 2018-04-07
            • 2014-02-25
            • 2015-12-04
            • 2014-09-10
            • 1970-01-01
            • 2015-09-14
            • 2015-10-08
            • 2017-07-21
            • 2016-09-26
            相关资源
            最近更新 更多