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

How to check if another directive is present on the same element

假设我有两个指令:

@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


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

您可以使用 Host() decorator, and also make it 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 级别上搜索。

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


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

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