使用 Angular 路由器时防止通过 href="#" 重定向

Prevent redirection through href="#" while using Angular Router

我一直在从事一个 Angular 项目,其中包括不同的库,最重要的是 ngx-datatable。

路由工作正常,除了 href="#" 的锚标记外,用户被重定向到 / 即使不需要。

我发现的所有解决方案都建议删除 # 或整个属性本身,但我不能这样做,因为它需要破解我将使用的所有库。

如果请求 URL 是 #,我有什么方法可以使用 Router hook 或其他东西来停止导航吗?

要达到预期结果,请使用 javascript:void(0) 作为 href 属性,而不是 #(如果您可以单独更改)

<a href="javascript:void(0);"></a>

选项 2: 更新所有 href 的通用解决方案,覆盖 href 属性,如下面的答案所述

@Directive({
  selector : '[href]'
})
export class MyLinkDirective {
  @Input() href: string;

  @HostListener('click', ['$event'])
  noop(event: MouseEvent) {
    if(this.href.length === 0 || this.href === '#') {
      event.preventDefault();
    }
  }
}

OP,我假设这是一个动态生成的元素,因为它是通过 ngx-datatable 生成的,这意味着您将必须查询该特定元素,然后向其添加一个事件侦听器,以防止事件的默认操作。

import { AfterViewInit, Component, ElementRef} from '@angular/core';

constructor(private elementRef:ElementRef) {}

ngAfterViewInit() {
  this.elementRef.nativeElement.querySelector('a[title="Expand/Collapse Group"]')
      .addEventListener('click', this.onClick.bind(this));
}

onClick(event) {
  event.preventDefault();
}

如果您不想导航,请不要使用锚点 link。我猜这是为了折叠和展开。如果你想让你的元素看起来像一个锚 link,那么只要给它添加 css 样式。您的 class name: datatable-icon-right 表示您显示的是一个图标。使用 div 或 i。你不必添加粗体标签 围绕你的文字。只需在 datatable-icon-right 中添加 font-weight:bold 即可。希望对你有帮助

已更新

我查看了 ngx-datatable 项目。我在分组示例中找到了这个

<ng-template let-group="group" let-expanded="expanded" ngx-datatable-group-header-template>
            <div style="padding-left:5px;">
              <a href="#"
                [class.datatable-icon-right]="!expanded"
                [class.datatable-icon-down]="expanded"
                title="Expand/Collapse Group"
                (click)="toggleExpandGroup(group)">
                <b>Age: {{ group.value[0].age }}</b>
              </a>
            </div>
          </ng-template>

您可以随意为展开元素添加任何占位符。只需添加一个 div 而不是锚点。如果样式看起来很奇怪,那么只需在 div 中添加一个额外的 class 并根据需要设置样式。例如:

.datatable-group-header .your-class{cursor:pointer...}

我在将大型 AngularJS 应用程序迁移到 Angular12 时遇到了类似的问题。这是一项足够复杂的工作,无需将每个损坏的锚标记重新设置为按钮(应该这样做)作为长期修复)。因此,我创建了一个临时指令,灵感来自上面的@naga-sai-a。

import { Directive, ElementRef, Input } from '@angular/core'

// TODO replace all of these uses with actual buttons. This is a fallback 
// from AngularJs default functionality

@Directive({
  selector : '[href]'
})
export class HrefDirective {
  @Input() href: string;

  constructor (private el: ElementRef) {}

  ngOnInit () {
    if(this.href.length === 0 || this.href === '#') {
      this.el.nativeElement.removeAttribute('href')
      this.el.nativeElement.style.cssText = "pointer:cursor"
    }
  }
}

这只是删除了 HREF 属性(阻止导航)并添加了光标指针。这是一个 hack,但不像试图停止事件传播那么讨厌。