Использование useHash: true прерывает открытие маршрутов Angular на новой странице
Я пытаюсь открыть маршрут 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 простых компонента:
/Страница 1
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, без проблем. Я попытался вручную добавить / # к открытому URL-адресу примерно 10 различными способами, но независимо от того, что я пытаюсь сделать, маршрутизатор видит URL-адрес новой вкладки как / (root), пока включен useHash.
Что мне здесь не хватает?
Я буду полностью честен, что я не очень разбираюсь во внутренней работе Angular HashLocationStrategy. Документация и обширные исследования не помогают. Я знаю, что мне действительно нужно использовать HashLocationStrategy из-за конфигурации сервера, на котором в конечном итоге будет размещено фактическое приложение, поэтому, к сожалению, я не могу усложнить задачу и просто установил для useHash значение false. Мне также нужно сделать это изнутри компонента, так как у меня есть обширная логика, которую мне нужно выполнить перед открытием новой вкладки в моем реальном приложении, поэтому в html тоже нет routerLink. У меня такое чувство, что мне здесь не хватает чего-то простого и фундаментального...
Любая помощь будет принята с благодарностью.
Рабочая минимальная репликация Stackblitz: https://stackblitz.com/edit/angular-ivy-yedwyk
2 ответа
Используйте location.prepareExternalUrl(). Определение метода prepareExternalUrl() из документации Angular ,
Нормализует внешний путь URL. Если данный URL-адрес не начинается с косой черты ('/'), добавляется перед нормализацией. Добавляет хэш, если используется HashLocationStrategy, или APP_BASE_HREF, если используется PathLocationStrategy.
Местоположение импорта из 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);
}
Поздно, но надеюсь, что это поможет кому-то другому.
Во-первых, вы пытаетесь странным образом перемещаться по приложению. Просто используйте следующий подход:
this.router.navigate(['/page2']);
Вы должны использовать экземпляр маршрутизатора, чтобы правильно разрешить навигацию. Также используйте свойство routerLink при использовании тегов:
<a routerLink="/page2">Navigate to /page2</a>