Как я могу условно использовать [href] или [routerLink] на привязке?
Мне нужно, чтобы эта же якорная ссылка была указана условно локально или на внешний ресурс. Я старался
<a [href]="outside?externalUrl:null" [routerLink]="outside?[]:['/route',id]" >test</a>
Но это не работает. Я не получаю никаких ошибок, но он указывает на ту же локальную страницу и игнорирует внешний URL. Есть идеи?
Другой вариант - создать ссылку, но я не могу найти никаких документов о том, как получить доступ к routerLink
внутри службы.
Редактировать: я знаю, что могу клонировать всю ссылку с помощью *ngIf
но я не хочу этого делать, моя ссылка содержит видео-тег с набором параметров
Ответы
Ответ 1
закончил делать это
<a [href]="_service.ifLink(outside,'/route',id,externalUrl)" >Link</a>
и сервис
public ifLink(outside,internal,internalId, external) {
if(outside)
return external
return `${internal}/${internalId}`
}
Я сохраняю значение внешнего URL-адреса в атрибуте temp и заменяю его на jQuery
на ngAfterViewInit
и добавляя событие click
, потому что, по-видимому, Angular 2 беспорядок с привязками кликов
ngAfterViewInit() {
if (this.replacing)
this.replaceHref()
}
links:any;
replaceHref() {
this.links = $('a')
for (var i = 0; i < this.links.length; i++) {
var extHrefEl = $(this.links[i]).attr('exthref')
if (extHrefEl) {
var extHref = $(this.links[i]).attr('exthref')
$(this.links[i]).attr('href', extHref);
$(this.links[i]).click(function () {
window.location.href = extHref;
});
}
}
}
и в компоненте
<a [attr.exthref]="externalUrl" [routerLink]="['/route',id]">Link</a>
Ответ 2
Самый простой способ - использовать *ngIf/else
:
<ng-container *ngIf="outside; else internalBlock">
<a [href]="externalUrl">External</a>
</ng-container>
<ng-template #internalBlock>
<a [routerLink]="['/route', id]">Internal</a>
</ng-template>
РЕДАКТИРОВАНИЕ № 1: (Гадкий обходной путь)
Поскольку вы не хотите использовать *ngIf
(я до сих пор не понимаю, почему), вы можете сделать это:
Шаблон:
<a href="javascript:void(0)" (click)="handleClick(outside, '/route', id, externalUrl)">Link</a>
Составная часть:
handleClick(outside: boolean, internalUrl: string, internalId: string, externalUrl: string): void {
if (outside) {
window.location.href = externalUrl;
// You can also use Location class of Angular
} else {
this.router.navigate(['${internalUrl}/${internalId}']);
}
}
Ответ 3
Для условного href, предваряющего attr. прежде чем href работал для меня, используя null в качестве значения, вот так:
[attr.href]="!item.subMenu ? item.url : null"
Ответ 4
Вы можете получить доступ к экземпляру routerLink, введя RouterLinkWithHref
в директиве.
Директива
@Directive({
selector: '[externalLink]'
})
export class ExternalLinkDirective {
@Input() externalLink: string;
constructor(
// Inject RouterLinkWithHref
@Optional() private link: RouterLinkWithHref
) {
if (!link) {
return;
}
// Save original onClick method
const onClick = link.onClick;
// Replace method with your own (I know this is not good idea)
link.onClick = (...args: any[]) => {
if (this.externalLink) {
// Process external url
window.location.href = this.externalLink;
return false;
} else {
// Process internal url by calling routerLink original method
return onClick.apply(link, args);
}
}
}
}
Применение:
<!-- Ignore router link and use external link -->
<a routerLink="/some/path" externalLink="https://google.com">Link</a>
Нижняя сторона этого подхода - href
атрибут в DOM не изменяется
Ответ 5
После долгих исследований я реализовал другой подход к этой проблеме, так как мой <a href>...</a>
содержит код внутри (например, интерактивный div). Например, я не хочу использовать ngIf
потому что это вынуждает меня дублировать div внутри кода. Так что это мое решение:
Компонент HTML
<div>
<a [href]="getRouterLink()" >
<div class="section">
<!-- stuff inside the div -->
</div>
</a>
</div>
Компонент JS
Component({
selector: 'app-home-section',
templateUrl: './home-section.component.html',
styleUrls: ['./home-section.component.scss']
})
export class HomeSectionComponent implements OnInit {
@Input() link: string;
constructor(private router: Router) { }
ngOnInit() {
}
isRouterLink() {
if (this.link) {
let firstLinkChar = this.link.charAt(0);
let isSlash = firstLinkChar == '/';
return isSlash;
}
return false;
}
getRouterLink() {
let url = this.isRouterLink() ? window.location.origin + this.link : 'http://' + this.link;
return url;
}
}
Это был единственный способ упростить его работу, потому что даже если я поместил "www.example.com" непосредственно в href
(с или без [ ]
), он всегда добавляет базовый URL. Это не красиво, но функционально.