3

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

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

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

/第2页

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 视为 /(根)。

我在这里想念什么?

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

任何帮助将不胜感激。

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

4

2 回答 2

0

使用 location.prepareExternalUrl()。Angular 文档中 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);
}

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

于 2021-11-25T01:08:37.737 回答
0

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

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

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

<a routerLink="/page2">Navigate to /page2</a>
于 2021-06-03T03:26:07.573 回答