Не удается отобразить routerLink во внутренней HTML в Angular - PullRequest
0 голосов
/ 12 января 2020

В коде компонента у меня есть поле с именем taggy, содержащее полный тег привязки. Сначала в моем HTML я отобразил его на экране, что, конечно же, не сработало, потому что я видел содержимое taggy только в дословной версии. В тексте написано буквально хазаа .

Один погуглив, я обнаружил свою ошибку. Я должен использовать внутренний HTML. Это работает, но вызывает перезагрузку браузера, поскольку мы используем href , а не routerLink . Естественно, я изменил значение taggy так, чтобы оно показывало routerLink вместо href . Однако, когда я это делаю, это работает вроде, но не совсем. В моем HTML у меня есть следующее.

{{taggy}}
<div [innerHTML]=taggy></div>
<div innerHTML=taggy></div>

Ни один из них не выдает работающую ссылку. Ближайшим является средний, так как он создает div и внутри него привязку. Однако в теге привязки нет атрибутов, и он содержит только текст, который должен прочитать пользователь. Информация о маршрутизации пропала.

Что делать?

Я нашел предложение , но это не очень хороший способ для go (даже Автор указывает, что это не лучший подход). Также есть this , но в моем случае это не актуально, так как я передаю строку другому компоненту.

Ответы [ 2 ]

1 голос
/ 17 января 2020

Как вы обнаружили, вы не можете иметь динамический c шаблон в Angular, потому что шаблоны связаны с компонентами как javascript. Если вы хотите узнать больше, проверьте эту проблему на github . В результате этого: динамические c шаблоны могут нарушить компиляцию AOT.

Вы также обнаружили, что для innerHTML объекта можно установить произвольное значение HTML, но routerLink не будет работать в этом контексте. Почему? Поскольку routerlink является директивой Angular, а не атрибутом HTML. Поскольку мы просто устанавливаем innerHTML, это не скомпилированный шаблон.

Итак, каково решение? Давайте вернемся назад и подумаем о том, что делает routerLink. Как оказалось, не так много. Взгляните на источник . В частности, это то, что он делает, когда щелкает элемент с директивой routerLink:

@HostListener('click')
onClick(): boolean {
  const extras = {
    skipLocationChange: attrBoolValue(this.skipLocationChange),
    replaceUrl: attrBoolValue(this.replaceUrl),
  };
  this.router.navigateByUrl(this.urlTree, extras);
  return true;
}

Он просто использует HostListener для отслеживания кликов и соответствующей маршрутизации. Мы можем сделать что-то подобное в нашем компоненте. Я назвал это FooterComponent, так как вы упомянули, что это был нижний колонтитул с Dynami c HTML:

import { Component, Input, HostListener } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-footer',
  template: '<div [innerHTML]="footerHtml"></div>'
})
export class FooterComponent {
  @Input() footerHtml: string = "";

  constructor(private router: Router) { }
  // Watch for clicks in our component
  @HostListener("click", ['$event'])
  onClick(event: MouseEvent) {
    // If we don't have an anchor tag, we don't need to do anything.
    if (event.target instanceof HTMLAnchorElement === false) { 
      return;
    }
    // Prevent page from reloading
    event.preventDefault();
    let target = <HTMLAnchorElement>event.target;
    // Navigate to the path in the link
    this.router.navigate([target.pathname]);
  }
}

Как вы можете видеть, он требует ввода, называемого footerHtml, который типа строки. Чтобы использовать его, мы добавим его куда-нибудь:

<app-footer [footerHtml]="footerHtml"></app-footer>

Где свойство footerHtml в нашем компоненте определяется следующим образом:

footerHtml = '<p>This is the footer with a <a href="/admin">link!</a></p>';

Когда элемент нажимается, мы проверяем чтобы убедиться, что пользователь нажал на гиперссылку. Если они это сделали, мы перемещаемся с помощью маршрутизатора и предотвращаем поведение по умолчанию. Вот рабочий пример StackBlitz . Надеюсь, это поможет!

0 голосов
/ 04 мая 2020

Исходя из вопроса, # Дин решение работает нормально, но не работает для внешней ссылки. То есть он может работать только для angular маршрута. Ниже мое решение для решения как внутренней, так и внешней ссылки / ссылки.

  import { Component, Input, HostListener } from '@angular/core';
  import { Router } from '@angular/router';

  import { Component, Input, HostListener } from '@angular/core';
  import { Router } from '@angular/router';

  @Component({
    selector: 'app-footer',
    template: '<div [innerHTML]="footerHtml"></div>'
  })
  export class FooterComponent {
    footerHtml = '<p>This is the innerHTML content with angular valid path  <a href="/admin">internal link!</a> and external link <a target="_blank" href="https://google.com">external link</a></p>';

    // Watch for clicks in our component
    @HostListener('click', ['$event'])
    onClick(event: MouseEvent) {
    this.routingService.urlLocator(event);
    // Do nothing if no anchor tag.
    if (event.target instanceof HTMLAnchorElement === false) {
      return;
    }

    // Prevent normal html anchor behaviour
    event.preventDefault();

    // Checks if the anchor has a full url name or if target is "_blank"
    // That is, target external url
    if (event.target.target === '_blank') {
      // open it in new window (You can decide to use window.location.href)
      window.open(event.target.href); 
    } else {
      // handle valid angular route path
      const target = <HTMLAnchorElement>event.target;
      this.router.navigate([target.pathname]);
    }
  }
}
...