如何有条件地在锚点上使用[href]或[routerLink]?

时间:2017-06-09 04:12:51

标签: angular angular-routing

我需要在本地有条件地指向相同的锚链接或外部资源。我试过了

<a [href]="outside?externalUrl:null"  [routerLink]="outside?[]:['/route',id]" >test</a>

但它不起作用。我没有收到任何错误,但它指向同一本地页面并忽略外部URL。有什么想法吗?

另一种选择是构建链接,但我找不到任何文档如何在服务中访问routerLink

编辑:我知道我可以使用*ngIf克隆整个链接,但我不想这样做,我的链接包含一个带有大量选项的视频标记

5 个答案:

答案 0 :(得分:19)

最简单的方法是使用*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}`]);
  }
}

答案 1 :(得分:2)

对于有条件的href,在attr之前。在href为我工作之前使用null作为值,如下所示:

[attr.href]="!item.subMenu ? item.url : null"

答案 2 :(得分:1)

您可以通过在指令中注入RouterLinkWithHref来访问 routerLink实例

<强>指令:

@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>

此方法的缺点 - DOM中的href属性未发生变化

答案 3 :(得分:0)

经过大量调查,我针对此问题采用了不同的方法,因为我的<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(带有或不带有[ ])中,它也总是附加到基本网址。它不漂亮,但是可以使用。

答案 4 :(得分:0)

对于我的用例,<a>标记内的内容中包含一些嵌套的html,因此我必须为此创建一个自定义组件。

该组件的主要作用是

  • 使用内容包含
  • 在上下文中使用ngTemplateOutlet
  • 有条件地显示带有<a>指令或routerLink的{​​{1}}标记。

  • href
route-or-redirect.component.ts
  • import { Component, ContentChild, Directive, Input, OnInit, TemplateRef, } from '@angular/core'; import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; export interface Bookmark { id: string; title: string; imgUrl: string; } @Directive({ selector: '[appLinkContent]', }) export class RouteOrRedirectLinkContentDirective {} @Component({ selector: 'app-router-or-redirect', templateUrl: './router-or-redirect.component.html', styleUrls: ['./router-or-redirect.component.scss'], }) export class RouteOrRedirectComponent implements OnInit { @Input() route = '/'; @Input() set externalLink(link: string) { this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(link); } @Input() redirect = false; @Input() bookmark!: Bookmark; @ContentChild(RouteOrRedirectLinkContentDirective, { read: TemplateRef }) linkContent: TemplateRef<RouteOrRedirectLinkContentDirective> | undefined; safeUrl: SafeResourceUrl | undefined; constructor(private sanitizer: DomSanitizer) {} ngOnInit(): void {} }
route-or-redirect.component.html
  • <a [routerLink]="route" *ngIf="!redirect; else redirectLink"> <ng-container *ngTemplateOutlet="linkContent; context: { $implicit: bookmark }" ></ng-container> </a> <ng-template #redirectLink> <a [attr.href]="safeUrl"> <ng-container *ngTemplateOutlet="linkContent; context: { $implicit: bookmark }" ></ng-container> </a> </ng-template>
route-or-redirect.component.ts