html - ตรวจสอบการคลิกนอกคอมโพเนนต์ Angular
ฉันจะตรวจสอบการคลิก นอก คอมโพเนนต์ใน Angular ได้อย่างไร?
คำตอบ #1
import { Component, ElementRef, HostListener, Input } from '@angular/core';
@Component({
selector: 'selector',
template: `
<div>
{{text}}
</div>
`
})
export class AnotherComponent {
public text: String;
@HostListener('document:click', ['$event'])
clickout(event) {
if(this.eRef.nativeElement.contains(event.target)) {
this.text = "clicked inside";
} else {
this.text = "clicked outside";
}
}
constructor(private eRef: ElementRef) {
this.text = 'no clicks yet';
}
}
ตัวอย่างที่ใช้งานได้ - คลิกที่นี่
คำตอบ #2
ทางเลือกหนึ่งสำหรับคำตอบของ AMagyar เวอร์ชันนี้ทำงานเมื่อคุณคลิกที่องค์ประกอบที่ถูกลบออกจาก DOM ด้วย ngIf
http://plnkr.co/edit/4mrn4GjM95uvSbQtxrAS?p=preview
private wasInside = false;
@HostListener('click')
clickInside() {
this.text = "clicked inside";
this.wasInside = true;
}
@HostListener('document:click')
clickout() {
if (!this.wasInside) {
this.text = "clicked outside";
}
this.wasInside = false;
}คำตอบ #3
การผูกกับการคลิกเอกสารผ่าน @Hostlistener มีค่าใช้จ่ายสูง มันสามารถและจะมีผลกระทบต่อประสิทธิภาพที่เห็นได้ชัดหากคุณใช้มากเกินไป (ตัวอย่างเช่น เมื่อสร้างส่วนประกอบ dropdown แบบกำหนดเองและคุณมีหลายอินสแตนซ์ที่สร้างขึ้นในฟอร์ม)
ฉันขอแนะนำให้เพิ่ม @Hostlistener() กับเหตุการณ์คลิกเอกสารเพียงครั้งเดียวภายในคอมโพเนนต์แอปหลักของคุณ เหตุการณ์นี้ควรผลักค่าขององค์ประกอบที่ถูกคลิกเข้าไปใน subject สาธารณะที่เก็บในบริการเครื่องมือสากล
@Component({
selector: 'app-root',
template: '<router-outlet></router-outlet>'
})
export class AppComponent {
constructor(private utilitiesService: UtilitiesService) {}
@HostListener('document:click', ['$event'])
documentClick(event: any): void {
this.utilitiesService.documentClickedTarget.next(event.target)
}
}
@Injectable({ providedIn: 'root' })
export class UtilitiesService {
documentClickedTarget: Subject<HTMLElement> = new Subject<HTMLElement>()
}
ผู้ที่สนใจในองค์ประกอบเป้าหมายที่ถูกคลิกควรสมัครรับข้อมูลต่อหัวข้อสาธารณะของบริการสาธารณูปโภคของเราและยกเลิกการสมัครเมื่อคอมโพเนนต์ถูกทำลาย
export class AnotherComponent implements OnInit {
@ViewChild('somePopup', { read: ElementRef, static: false }) somePopup: ElementRef
constructor(private utilitiesService: UtilitiesService) { }
ngOnInit() {
this.utilitiesService.documentClickedTarget
.subscribe(target => this.documentClickListener(target))
}
documentClickListener(target: any): void {
if (this.somePopup.nativeElement.contains(target))
// Clicked inside
else
// Clicked outside
}
คำตอบ #4
ปรับปรุงคำตอบของ J. Frankenstein:
@HostListener('click')
clickInside($event) {
this.text = "clicked inside";
$event.stopPropagation();
}
@HostListener('document:click')
clickOutside() {
this.text = "clicked outside";
}