在一个组件中包含许多不同组件的应用程序中,我有一个自定义自动建议框.如果用户点击自动建议框(或包含自动建议框的元素)的任何位置,则应关闭该框.
这就是我在jQuery中要做的事情:
$(document).on('click','body',function(e) { if(e.target!='.suggestBox' && $(e.target).parent('.suggestBox').length <1 ) { $('.suggestBox').remove(); } });
但是在我的Angular Dart模板中,我有:
index.html的:
<body> <my-app> // sub component // sub sub component </my-app> </body>
我可以想到在my-app组件中检测到最顶层包装器上的点击并将操作发送到子组件但是这仍然不是主体点击的可能性.
解决方法
@H_403_30@<button (click)="show = true">show dropdown</button> <div #suggestBox *ngIf="show">...</div>
class AutoSuggestComponent { bool show = false; @ViewChild('suggestBox') ElementRef suggestBox; @HostListener('document:click',[r'$event']) onDocumentClick(MouseEvent e) { if((suggestBox.nativeElement as HtmlElement).contains(e.target)) { // inside the dropdown } else { // outside the dropdown } } }
没有经过测试,按钮和div元素只是组件外观的粗略近似值.
另见How can I close a dropdown on click outside?
更新
Angular 5不支持像document这样的全局事件处理程序:…
而是使用命令式变体
class AutoSuggestComponent implements AfterViewInit,OnDestroy { bool show = false; @ViewChild('suggestBox') ElementRef suggestBox; StreamSubscription _docClickSub; @override void ngAfterViewInit() { _docClickSub = document.onClick.listen((e) { if((suggestBox.nativeElement as HtmlElement).contains(e.target)) { // inside the dropdown } else { // outside the dropdown } }); } @override void onDestroy() { _docClickSub?.cancel(); } }