用 ngIf 单击外部指令?
Click outside directive with ngIf?
如果点击是在具体 DOM 元素之外,我使用以下指令来检测和隐藏块:
import {
Directive,
ElementRef,
Output,
EventEmitter,
HostListener
} from "@angular/core";
@Directive({
selector: "[clickOutside]"
})
export class ClickOutsideDirective {
constructor(private _elementRef: ElementRef) {}
@Output()
public clickOutside = new EventEmitter();
@HostListener("document:click", ["$event.target"])
public onClick(targetElement) {
const clickedInside = this._elementRef.nativeElement.contains(
targetElement
);
this.clickOutside.emit(clickedInside);
}
}
我已将此指令应用于元素:
<div class="action" (click)="open()">Open</div>
<div
class="search_content"
*ngIf="_searchContentOpen"
clickOutside
(clickOutside)="clickOutside($event)"
></div>
组件代码为:
open(): void {
this._searchContentOpen = !this._searchContentOpen;
}
问题是当我调用 click 时我将 this._searchContentOpen
设置为 true/false。
取决于它我显示应用指令的块。但是当 ngIf 工作时,指令也总是同步工作。因此结果块永远不会显示。
如何解决?
这是我的两个选择:
1) 在触发器
上使用event.stopPropagation()
<div class="action" (click)="open(); $event.stopPropagation()">Open</div>
2) 仅在应用指令后处理点击
@Directive({
selector: '[clickOutside]'
})
export class ClickOutsideDirective implements OnInit {
@Output() clickOutside = new EventEmitter();
captured = false;
constructor(private elRef: ElementRef) { }
@HostListener('document:click', ['$event.target'])
onClick(target) {
if (!this.captured) {
return;
}
if (!this.elRef.nativeElement.contains(target)) {
this.clickOutside.emit();
};
}
ngOnInit() {
fromEvent(document, 'click', { capture: true }).pipe(take(1))
.subscribe(() => this.captured = true);
/* or
document.addEventListener('click', () => this.captured = true, {
capture: true,
once: true
});
*/
}
}
如果点击是在具体 DOM 元素之外,我使用以下指令来检测和隐藏块:
import {
Directive,
ElementRef,
Output,
EventEmitter,
HostListener
} from "@angular/core";
@Directive({
selector: "[clickOutside]"
})
export class ClickOutsideDirective {
constructor(private _elementRef: ElementRef) {}
@Output()
public clickOutside = new EventEmitter();
@HostListener("document:click", ["$event.target"])
public onClick(targetElement) {
const clickedInside = this._elementRef.nativeElement.contains(
targetElement
);
this.clickOutside.emit(clickedInside);
}
}
我已将此指令应用于元素:
<div class="action" (click)="open()">Open</div>
<div
class="search_content"
*ngIf="_searchContentOpen"
clickOutside
(clickOutside)="clickOutside($event)"
></div>
组件代码为:
open(): void {
this._searchContentOpen = !this._searchContentOpen;
}
问题是当我调用 click 时我将 this._searchContentOpen
设置为 true/false。
取决于它我显示应用指令的块。但是当 ngIf 工作时,指令也总是同步工作。因此结果块永远不会显示。
如何解决?
这是我的两个选择:
1) 在触发器
上使用event.stopPropagation()
<div class="action" (click)="open(); $event.stopPropagation()">Open</div>
2) 仅在应用指令后处理点击
@Directive({
selector: '[clickOutside]'
})
export class ClickOutsideDirective implements OnInit {
@Output() clickOutside = new EventEmitter();
captured = false;
constructor(private elRef: ElementRef) { }
@HostListener('document:click', ['$event.target'])
onClick(target) {
if (!this.captured) {
return;
}
if (!this.elRef.nativeElement.contains(target)) {
this.clickOutside.emit();
};
}
ngOnInit() {
fromEvent(document, 'click', { capture: true }).pipe(take(1))
.subscribe(() => this.captured = true);
/* or
document.addEventListener('click', () => this.captured = true, {
capture: true,
once: true
});
*/
}
}