在降价链接中使用角度路由器

问题描述 投票:0回答:4

我正在使用 ngx-markdown 来呈现我的常见问题解答,其中,我链接到外部资源(以

http
开头)和内部内容(以
/
开头)。

我想将角度路由器传递到我的markedOptionsFactory,以便将其用于本地资源。

有没有办法在导入模块时在装饰器中传递角度路由器:

imports: [
    [...]
    MarkdownModule.forRoot({
        provide: MarkedOptions,
        useFactory: markedOptionsFactory,
    }),
    [...]
],

仅供参考,我的

markedOptionsFactory
看起来像:

export function markedOptionsFactory(): MarkedOptions {
    const renderer = new MarkedRenderer();

    renderer.link = (href: string, title: string, text: string) => {
        const isLocalLink = /^\//.test(href);
        const target = isLocalLink ? '_self' : '_blank';
        const hrefContent = isLocalLink ? `javascript:router.navigateByUrl('${href}')` : href;

        return `<a href="${hrefContent}" target="${target}">${text}</a>`;
};

    return {
        renderer: renderer,
        [...]
    };
}
angular markdown
4个回答
2
投票

这是我的解决方案,基于建议这里

定义角度指令

import { Directive, HostListener } from '@angular/core';
import { Router } from "@angular/router";

@Directive({
  selector: '[appInterceptRouterlink]'
})
export class InterceptRouterlinkDirective {

  constructor(private router: Router) { }

  @HostListener("click", ["$event"])
  public onClick(e: MouseEvent): void {
    const srcElem = e.target;
    if (srcElem instanceof HTMLAnchorElement)
    {
      const baseURI = srcElem.baseURI ;
      const href = srcElem.href ;

      if (href.startsWith(baseURI))
      {
        const baseURILength = baseURI.length;
        const routerlink = href.substring(baseURILength);
        e.preventDefault();
        e.stopPropagation();
        this.router.navigate([routerlink]);
      }
    }
  }
}

在 markdown 标签中使用指令,在我的例子中如下

<markdown [data]="markdown" appInterceptRouterlink></markdown>

指令中的 HostListener 查找以基本 URL 开头的链接并将它们作为路由器链接处理。


1
投票

我没有从 Angular 找到直接的解决方案。我必须从 Marked.js 创建一个自定义事件,然后在 DOM 树中更高的位置捕获它。

这里是我工作的一些代码:

  • 第一:从链接触发事件(而不是默认的路由行为)
renderer.link = (href: string, title: string, text: string) => {
  const isLocalLink = /^\//.test(href);

  let hrefContent;
  if (isLocalLink) {
    hrefContent = `javascript:document.dispatchEvent(new CustomEvent('routeTo', {detail: '${href}'})); void(0)`;
  } else {
    hrefContent = href;
  }

  return `<a href="${hrefContent}">${text}</a>`;
};
  • 然后:从可能的最高组件/模块捕获该事件:
this.window.document.addEventListener('routeTo', (e: CustomEvent) => {
  e.preventDefault();
  router.navigateByUrl(e.detail);
}, false);

小心使用 Internet Explorer,您将需要一个用于自定义事件的 Polyfill


0
投票

您可以关注这个答案 希望这有帮助!


0
投票

我不得不稍微修改菲尔斯的答案,但现在它也可以正常工作了。它无法正确处理片段。

@Component({
    selector: 'app-markdown',
    standalone: true,
    templateUrl: './markdown.component.html',
    styleUrl: './markdown.component.scss',
    imports: [CommonModule, MarkedPipe],
})
export class MarkdownComponent {
    private _router = inject(Router);
    @Input({ required: true }) content!: string;

    public onClick(e: MouseEvent): void {
        const srcElem = e.target;
        if (srcElem instanceof HTMLAnchorElement) {
            const href = srcElem.href;
            const isLocalLink = href.startsWith(srcElem.baseURI);
            if (isLocalLink) {
                e.preventDefault();
                e.stopPropagation();
                
                const url = new URL(href);
                const fragment = url.hash ? url.hash.substring(1) : undefined;
                this._router.navigate([url.pathname], { fragment });
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.