无法在Angular的innerHTML中呈现routerLink [英] Can't render routerLink in innerHTML in Angular

查看:179
本文介绍了无法在Angular的innerHTML中呈现routerLink的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在组件代码中,我有一个称为taggy的字段,其中包含完整的锚标签.首先,在HTML中,我将其呈现到屏幕上,这当然是行不通的,因为我只在逐字记录版本中看到了标签的内容.文字字面意思是< a href ="blopp/1337"> hazaa< a> .

In the component code I have a field called taggy containing a full anchor tag. At first, in my HTML, I rendered it to the screen, which, of course didn't work out because I only saw contents of taggy in the verbatim version. The text said literally <a href="blopp/1337">hazaa<a>.

一个谷歌搜索,我发现了我的错误.我应该使用 innerHTML .它可以工作,但会导致浏览器重新加载,因为我们使用的是 href 而不是 routerLink .自然,我更改了taggy的值,因此它说的是 routerLink 而不是 href .但是,当我这样做时,它有点奏效,但效果并不理想.在我的HTML中,我有以下内容.

One googling away, I discovered my mistake. I'm supposed to use innerHTML. It works but causes the browser to reload, since we're using a href and not routerLink. Naturally, I changed the value of taggy so it says routerLink instead of href. However, when I do so, it works kind of but not quite. In my HTML I have the following.

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

没有一个产生有效的链接.最接近的是中间的一个,因为它创建了一个div,并在其中创建了一个锚点.但是,anchor标签上没有属性,它仅包含用户应阅读的文本.路由信息不见了.

None of those produce a working link. The closest is the middle one, as it creates a div and inside it an anchor. However, there's no attributes on the anchor tag and it only contains the text that the user's supposed to read. The routing information is gone.

该怎么办?

我发现了一个建议,但这并不是一个好方法(即使作者指出,这不是最好的方法).也有 ,但这与我的情况无关,因为我要将字符串传递给另一个组件.

I've found a suggestion but it doesn't feel as a good way to go (even author indicates that it's not the best approach). There's also this but it's not relevant in my case as I'm passing the string to another component.

推荐答案

您已经发现,由于Angular中的模板与组件捆绑在一起,因此您在Angular中没有动态模板.如果您想了解更多信息,请在github上查看此问题.结果是:动态模板会破坏AOT编译.

As you've discovered, you can't have a dynamic template in Angular because the templates are bundled with components as javascript. If you want to learn more, check out this issue on github. The upshot of it is: dynamic templates would break AOT compilation.

您还发现可以将对象的innerHTML设置为任意HTML,但是routerLink在这种情况下不起作用. 为什么?因为routerlink是Angular指令,而不是HTML属性.由于我们只是设置innerHTML,因此它不是已编译的模板.

You have also discovered that you can set the innerHTML of an object to arbitrary HTML, but routerLink won't work in that context. Why? Because routerlink is an Angular directive, not an HTML attribute. Since we are just setting the innerHTML, it's not a compiled template.

那么,解决方案是什么?让我们备份一下,首先考虑routerLink在做什么.事实证明,数量不多.看看 .具体来说,这是单击带有routerLink指令的元素时的操作:

So, what's the solution? Let's back up and think about what routerLink is doing in the first place. As it turns out, not much. Take a look at the source. Specifically, this is what it's doing when an element with the routerLink directive is clicked:

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

它只是使用HostListener监视点击并相应地进行路由.我们可以在组件中执行类似的操作.我称它为FooterComponent,因为您提到这是动态HTML的页脚:

It's just using HostListener to monitor clicks, and routing accordingly. We can do something similar in our component. I've called it FooterComponent since you mentioned that this was a footer with dynamic 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的输入,它是字符串类型.要使用它,我们将其添加到某处:

As you can see, it takes in input called footerHtml, which is of type string. To use it, we will add this somewhere:

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

我们组件中的footerHtml属性定义如下:

Where the footerHtml property in our component is defined as follows:

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

单击元素时,我们检查以确保用户单击了超链接.如果他们这样做,我们将使用路由器进行导航,并防止出现默认行为.这是一个工作正常的StackBlitz示例.希望这会有所帮助!

When the element is clicked, we check to make sure the user clicked on a hyperlink. If they did, we navigate using the router and prevent the default behavior. Here's a working StackBlitz example. Hope this helps!

这篇关于无法在Angular的innerHTML中呈现routerLink的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆