Как я могу условно использовать [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. Это не красиво, но функционально.