【问题标题】:Get the component name of links when clicked点击时获取链接的组件名称
【发布时间】:2019-03-27 20:02:52
【问题描述】:

在我正在构建的 Web 应用程序中,当单击任何链接并更改路由时,我需要知道单击的链接属于哪个组件。

例如,如果标题组件中的任何链接被点击“关于我们”
例如,我需要控制台日志“标题组件”,
但是如果我从页脚组件中单击“关于我们”,我会得到“页脚组件”等等......

应该为所有可以改变路由的<a>元素添加这个功能。

【问题讨论】:

  • 请尝试分享一个最小的、完整的和可验证的示例,说明您迄今为止所做的尝试,以供其他人帮助。
  • 理论上,如果您想不惜一切代价避免更新<a> 标签,您可以在页眉和页脚中添加HostListener,以跟踪其中任何一个发生点击的时间。您可以将其与 observable 结合使用来确定用户是如何导航的。我强烈建议不要这样做..

标签: javascript angular web-applications hyperlink components


【解决方案1】:

您可以创建属性directive。例如称为linkTracker 并将其添加到您的a 标签中,如下所示。然后在附加到点击的指令中,读取值并记录它

<a linkTracker="about us">

<a linkTracker="footer">

link-tracker.directive.ts

@Directive({
    selector: '[linkTracker]',
    exportAs: 'linkTracker'
})
export class LinkTrackerDirective
{
    @Input() linkTracker: string;

    @HostListener('click', ['$event.target'])
    onClick()
    {
       console.log(this.linkTracker);
    }
 }

您可以找到如何创建指令here的指南

【讨论】:

【解决方案2】:

你可以用指令解决你的问题:

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

    @Directive({
       selector: '[myParent]'
    })
    export class MyParentDirective {
        @Input('myParent') parent: string;
        @HostListener('click') onMouseClick() {
            this.showParent();
        }
        constructor() { }

        showParent(){
            console.log(this.parent)
        }
    }

然后你就可以这样使用了

<a myParent="footer">About Us</a>

【讨论】:

【解决方案3】:

如果您已经知道父组件,我可以建议另一种解决方案。 您可以为要在指令中拦截的每个父级使用父级注入。 所以“链接指令”将是这样的(你必须实现你所需要的):

import { Directive, HostListener, Input, Host, Inject, forwardRef,Optional } from '@angular/core';
import { FooterComponent } from './footer/footer.component';
import { NavbarComponent } from './navbar/navbar.component';

  @Directive({
      selector: 'a'
  })
  export class LinkDirective {
      @HostListener('click') onMouseClick() {
          this.showParent();
      }

      parent: FooterComponent | NavbarComponent;

      constructor(@Optional() @Inject(forwardRef(() => FooterComponent)) private footer?: FooterComponent,
      @Optional() @Inject(forwardRef(() => NavbarComponent)) navbar?: NavbarComponent) { 
        console.log(footer, navbar)
        if(footer){
          this.parent = footer;
        }
        if(navbar){
          this.parent = navbar
        }
        if(!this.parent){
          this.parent = null;
        }
      }

      showParent(){
          console.log(this.parent, (this.parent) ? this.getTagName(this.parent.constructor.name) : null);
      }

      getTagName(el: string){
        return 'my-' + el.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
      }
  }

在这种情况下,我想查看“a”标签是否在NavbarFooter 内,中间的其他组件将被忽略。 如果要拦截的两个组件在另一个组件中,则可能会出现问题,因为两者都将被注入指令中,所以我不知道这是否是解决问题的最佳方法,但在这种情况下,您可以避免在每个链接中写入指令名称。

我做了一点stackblitz 来向您展示它是如何工作的。

顺便说一句,如果您确定每个链接都是注入指令中的组件的直接子级,您可以在 @Optional() 之前添加 @Host() 装饰器,您将获得此行为并解决问题为每个链接注射一次以上:

NavbarComponent 注入:

<my-navbar>
    <a>Test</a>
</my-navbar>

NavbarComponent 未注入:

<my-navbar>
    <my-middle-component>
        <a>Test</a>
    </my-middle-component>
</my-navbar>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多