如何检查同一元素上是否存在另一个指令
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
假设我有两个指令:
@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