如果您已经知道父组件,我可以建议另一种解决方案。
您可以为要在指令中拦截的每个父级使用父级注入。
所以“链接指令”将是这样的(你必须实现你所需要的):
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”标签是否在Navbar 或Footer 内,中间的其他组件将被忽略。
如果要拦截的两个组件在另一个组件中,则可能会出现问题,因为两者都将被注入指令中,所以我不知道这是否是解决问题的最佳方法,但在这种情况下,您可以避免在每个链接中写入指令名称。
我做了一点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>