如何检查同一元素上是不是存在另一个指令

Posted

技术标签:

【中文标题】如何检查同一元素上是不是存在另一个指令【英文标题】:How to check if another directive is present on the same element如何检查同一元素上是否存在另一个指令 【发布时间】:2019-12-10 06:23:40 【问题描述】:

假设我有两个指令:

@Directive(
  selector: '[appDirective1]'
)
export class Directive1Directive 

  public alone = true;

  constructor(private element: ElementRef<htmlInputElement>)  

  ngOnInit() 
    if (this.alone) 
      this.element.nativeElement.innerHTML = "I am alone";
     else 
      this.element.nativeElement.innerHTML = "I have a friend";
    
  


@Directive(
  selector: '[appDirective2]'
)
export class Directive2Directive 

  constructor()  


如果Directive2 出现在同一元素上,我希望Directive1 改变其行为。例如,它们应该有不同的行为。

<div appDirective1></div>
<div appDirective1 appDirective2></div>

我是否可以在不添加服务以促进通信的情况下执行此操作*?

StackBlitz 示例:https://stackblitz.com/edit/angular-bgqd15


*我想避免为此创建新服务,因为这感觉有点矫枉过正。

【问题讨论】:

【参考方案1】:

我认为Reactgular's answer 更好,因为它可以根据需要轻松应用于任一指令。


根据这两个指令的关系,我找到了以下解决方案:

Directive1 明确检查Directive2

@Directive(
  selector: '[appDirective1]'
)
export class Directive1Directive 

  public alone = true;

  @Input("appDirective2")
  public appDirective2: any;

  constructor(private element: ElementRef<HTMLInputElement>)  

  ngOnInit() 
    if (this.appDirective2 !== undefined) 
      this.alone = false;
    
    if (this.alone) 
      this.element.nativeElement.innerHTML = "I am alone";
     else 
      this.element.nativeElement.innerHTML = "I have a friend";
    
  

StackBlitz 示例:https://stackblitz.com/edit/angular-5w63vu

Directive2提供一个钩子告诉Directive1

@Directive(
  selector: '[appDirective1]'
)
export class Directive1Directive 

  public alone = true;

  constructor(private element: ElementRef<HTMLInputElement>)  

  ngOnInit() 
    this.setContent();
  

  setFriend() 
    this.alone = false;
    this.setContent();
  

  setContent() 
    if (this.alone) 
      this.element.nativeElement.innerHTML = "I am alone";
     else 
      this.element.nativeElement.innerHTML = "I have a friend";
    
  


@Directive(
  selector: '[appDirective2]'
)
export class Directive2Directive 

  constructor(@Self() private otherDirective: Directive1Directive )  

  ngOnInit() 
    this.otherDirective.setFriend();
  

StackBlitz 示例:https://stackblitz.com/edit/angular-bag8wa

【讨论】:

【参考方案2】:

您可以使用Host() 装饰器通过构造函数注入相邻指令,也可以将其设为Optional()

  constructor(@Optional() @Host() public friend: Directive2Directive)  

  ngOnInit() 
    if (this.friend) 
      this.element.nativeElement.innerHTML = "I have a friend";
     else 
      this.element.nativeElement.innerHTML = "I am alone";
    
  

组件、指令和提供程序是可注入的,您可以将 DI 限制为仅在当前 主机 级别上搜索。

【讨论】:

您是否更喜欢@Host 而不是@Self (angular.io/api/core/Self)?我对其中的区别不是很熟悉,但我最初的印象是@Host 会撒下更大的网 @Vlad274 @Self() 从当前主机开始向上走直到找到提供者。 @Host() 只查看当前主机,如果没有找到就停止。 哇,@Self 实际上是更广泛的网络!感谢您的信息! @Vlad274 我感觉@Self()是默认的,因为我们也有@SkipSelf()所以不使用@Self()有什么区别呢?所以这就是为什么我认为这是默认设置,但我检查了文档并无法在那里确认。

以上是关于如何检查同一元素上是不是存在另一个指令的主要内容,如果未能解决你的问题,请参考以下文章

检查一个列表元素中的元素是不是存在于另一个列表中

excel如何查询一组数据在另一个表格中是不是存在同一组数据?

如何检查Mysql中是不是存在数组元素?

检查 div 内容是不是已经存在于另一个 div 中?

如何在 Playwright.js 中检查页面上是不是存在元素

如何检查一个数组是不是包含另一个数组的任何元素