【问题标题】:Using 'useHash: true' breaks opening of Angular routes in new page使用“useHash:true”会破坏新页面中 Angular 路由的打开
【发布时间】:2020-10-23 14:02:09
【问题描述】:

我正在尝试在新选项卡中打开 Angular 路由,但在将 {useHash: true} 添加到路由器后遇到问题。在尝试 useHash 之前它工作得很好,打开了选项卡,并把我带到了我想要的组件。现在看来,无论我使用什么 URL 打开新选项卡,路由器都认为我正在尝试访问 root ("/")。

为了重现,我有一个非常简单的角度路由器:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { Page2Component } from './page2.component';
import { Page1Component } from './page1.component';

const routes: Routes = [
    { 
        path: 'page1', 
        component: Page1Component
    },
    {
        path: 'page2',
        component: Page2Component
    },
  { 
        path: '',
        component: Page1Component
    }
];

@NgModule({
  imports: [RouterModule.forRoot(routes, {useHash: true})],
  exports: [RouterModule]
})
export class AppRoutingModule { }

这允许查看 2 个简单的组件:

/page1

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

@Component({
  selector: 'app-page1',
  template: `<p>page1 works!</p>
             <button (click)="openNewTab()">OPEN NEW TAB</button>`,
  styleUrls: ['./app.component.css']
})
export class Page1Component implements OnInit {

    constructor(private router:Router) { }

    ngOnInit(): void {
    }

    openNewTab():void {
        console.log('Opening new tab...');
        const url = this.router.serializeUrl(
            this.router.createUrlTree(['page2'])//, 
        );
        window.open(url);
    }
}

/page2

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-page2',
  template: `<p>page2 works!</p>`,
  styleUrls: ['./app.component.css']
})
export class Page2Component implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}

基本上,当您单击位于 some.url.com/#/page1 的按钮时,Angular 应该会打开一个显示 some.url.com/#/page2 的新选项卡。正如我清楚地看到的那样,实际发生的情况是它试图打开 some.url.com/page2。请注意缺少 /#。现在,如果我将 useHash 设置为 false,我可以从 some.url.com/page1 转到 some.url.com/page2,没问题。我已经尝试手动将 /# 添加到我以大约 10 种不同方式打开的 url,但无论我尝试什么,只要启用了 useHash,路由器就会将新选项卡的 url 视为 /(root)。

我错过了什么?

老实说,我对 Angular HashLocationStrategy 的内部工作原理并不了解。文档和广泛的研究没有帮助。我知道由于最终将托管实际应用程序的服务器的配置,我确实需要使用 HashLocationStrategy,所以不幸的是,我无法轻松将 useHash 设置为 false。我还必须从组件内部执行此操作,因为在我的实际应用程序中打开新选项卡之前我需要执行大量逻辑,因此 html 中也没有 routerLink。我有一种感觉,我在这里遗漏了一些简单而基础的东西......

我们将非常感谢提供任何帮助。

工作最小的 Stackblitz 复制:https://stackblitz.com/edit/angular-ivy-yedwyk

【问题讨论】:

    标签: angular typescript routes angular-routing hash-location-strategy


    【解决方案1】:

    首先,您正试图以一种奇怪的方式浏览应用程序。只需使用以下方法:

    this.router.navigate(['/page2']);
    

    您必须使用路由器实例来正确解析导航。另外,在使用标签时使用 routerLink 属性:

    <a routerLink="/page2">Navigate to /page2</a>
    

    【讨论】:

      【解决方案2】:

      使用 location.prepareExternalUrl()。 从Angular documentation定义prepareExternalUrl()方法,

      规范化外部 URL 路径。如果给定的 URL 不以前导斜杠 ('/') 开头,则在规范化之前添加一个。如果 HashLocationStrategy 正在使用,则添加哈希,如果 PathLocationStrategy 正在使用,则添加 APP_BASE_HREF。

      从 Angular Common 导入位置:

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

      向构造函数添加定位服务:

      constructor(private router:Router,
                  private location: Location) { }
      

      使用 this.location.prepareExternalUrl 创建一个带有 # 的 url,以便您可以使用 window.open(url) 打开它:

      openNewTab():void {
          console.log('Opening new tab...');
          const url = this.location.prepareExternalUrl(this.router.serializeUrl(
              this.router.createUrlTree(['page2'])
          ));
          window.open(url);
      }
      

      晚了,但希望这对其他人有帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-12
        • 1970-01-01
        • 2018-03-06
        • 2015-07-31
        • 1970-01-01
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        相关资源
        最近更新 更多