单击外部 angular 组件
Click outside angular component
我知道围绕这个问题有无数的问题,我尝试了所有的解决方案,但没有一个适合我的需要。尝试过指令,直接在我的组件中尝试过,但一次都没有用。
所以我的情况是这样的;我有一个表格视图,在每个表格视图的末尾,您可以通过单击一个图标来打开一个小的下拉菜单。弹出的下拉框是一个小组件。所以在我的父组件中它看起来像这样;
<tbody>
<tr *ngFor="let rows of subscriptionTable.data; let i = index;">
<td *ngFor="let cell of subscriptionTable.data[i].data">
<!-- Table actions -->
<div *ngIf="cell.actions && cell.actions.length > 0">
<app-dropdown
[actions] = cell.actions
(onActionClicked) = "handleSubscriptionAction($event, i)"
>
</app-dropdown>
</div>
</td>
</tr>
</tbody>
所以我正在渲染多个如下所示的子应用程序下拉组件;
<div class="fs-action">
<div class="fs-action__dots" (click)="openActionSheet($event)">
<span class="fs-action__dot"></span>
<span class="fs-action__dot"></span>
<span class="fs-action__dot"></span>
</div>
<ul class="fs-action__list">
<li
class="fs-action__item"
*ngFor="let action of actions; let i = index;"
(click)="actionClicked( $event, i )"
[ngClass]="{'fs-action__item--danger': action.type === 'destructive' }"
>
{{ action.label }}
</li>
</ul>
</div>
我现在想要做的是,只要我在 fs-action 元素外单击,下拉菜单就会消失。我想在 app-dropdown
组件内执行此操作,然后与该组件相关的所有内容都在同一位置。
但是只要我附加指令或其他任何内容,就会为每一行添加 hostlistener
get。然后每次外部点击都会被多次触发。检查我是否在 action 元素外部单击会成为一种负担,因为它会为所有其他 hostlisteners
呈现 false,而为活动元素呈现 true。
这个问题在这个 stackblitz 中得到了说明; https://stackblitz.com/edit/angular-xjdmg4
我评论了导致内部问题的部分 dropdown.component.ts
;
public onClickOutside( event ) {
// It executes 3 times, for each of the items that is added
// Even when clicking inside the dropdown, it calls this function
console.log("click")
}
我用指令来处理类似的情况。
安装:
npm install --save ng-click-outside
然后导入你的模块
import { ClickOutsideModule } from 'ng-click-outside';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, ClickOutsideModule],
bootstrap: [AppComponent]
})
class AppModule {}
在你的组件中
@Component({
selector: 'app',
template: `
<div (clickOutside)="onClickedOutside($event)">Click outside this</div>
`
})
export class AppComponent {
onClickedOutside(e: Event) {
console.log('Clicked outside:', e);
}
}
它有一些选项。您可以在 https://www.npmjs.com/package/ng-click-outside
中看到它
此致
只需使用 (click) 事件绑定,从组件的实例传递一个函数就可以了。
解法:
声明指令 ClickOutside 如下所示:
@Directive({
selector: '[clickOutside]',
})
export class ClickOutsideDirective {
@Output('onClickOutside') onClickOutside = new EventEmitter<MouseEvent>();
constructor(private _eref: ElementRef) {}
@HostListener('document:click', ['$event', '$event.target'])
onDocumentClicked(event: MouseEvent, targetElement: HTMLElement) {
if (targetElement && document.body.contains(targetElement) && !this._eref.nativeElement.contains(targetElement)) {
this.onClickOutside.emit(event);
}
}
}
}
<div clickOutside (onClickOutside)="onClickOutside()">
...
</div>
并且在名为 ng-click-outside.
的 npm 模块中有一个指令
安装:npm install --save ng-click-outside
阅读下面 link 中的完整文档:
我知道围绕这个问题有无数的问题,我尝试了所有的解决方案,但没有一个适合我的需要。尝试过指令,直接在我的组件中尝试过,但一次都没有用。
所以我的情况是这样的;我有一个表格视图,在每个表格视图的末尾,您可以通过单击一个图标来打开一个小的下拉菜单。弹出的下拉框是一个小组件。所以在我的父组件中它看起来像这样;
<tbody>
<tr *ngFor="let rows of subscriptionTable.data; let i = index;">
<td *ngFor="let cell of subscriptionTable.data[i].data">
<!-- Table actions -->
<div *ngIf="cell.actions && cell.actions.length > 0">
<app-dropdown
[actions] = cell.actions
(onActionClicked) = "handleSubscriptionAction($event, i)"
>
</app-dropdown>
</div>
</td>
</tr>
</tbody>
所以我正在渲染多个如下所示的子应用程序下拉组件;
<div class="fs-action">
<div class="fs-action__dots" (click)="openActionSheet($event)">
<span class="fs-action__dot"></span>
<span class="fs-action__dot"></span>
<span class="fs-action__dot"></span>
</div>
<ul class="fs-action__list">
<li
class="fs-action__item"
*ngFor="let action of actions; let i = index;"
(click)="actionClicked( $event, i )"
[ngClass]="{'fs-action__item--danger': action.type === 'destructive' }"
>
{{ action.label }}
</li>
</ul>
</div>
我现在想要做的是,只要我在 fs-action 元素外单击,下拉菜单就会消失。我想在 app-dropdown
组件内执行此操作,然后与该组件相关的所有内容都在同一位置。
但是只要我附加指令或其他任何内容,就会为每一行添加 hostlistener
get。然后每次外部点击都会被多次触发。检查我是否在 action 元素外部单击会成为一种负担,因为它会为所有其他 hostlisteners
呈现 false,而为活动元素呈现 true。
这个问题在这个 stackblitz 中得到了说明; https://stackblitz.com/edit/angular-xjdmg4
我评论了导致内部问题的部分 dropdown.component.ts
;
public onClickOutside( event ) {
// It executes 3 times, for each of the items that is added
// Even when clicking inside the dropdown, it calls this function
console.log("click")
}
我用指令来处理类似的情况。 安装:
npm install --save ng-click-outside
然后导入你的模块
import { ClickOutsideModule } from 'ng-click-outside';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, ClickOutsideModule],
bootstrap: [AppComponent]
})
class AppModule {}
在你的组件中
@Component({
selector: 'app',
template: `
<div (clickOutside)="onClickedOutside($event)">Click outside this</div>
`
})
export class AppComponent {
onClickedOutside(e: Event) {
console.log('Clicked outside:', e);
}
}
它有一些选项。您可以在 https://www.npmjs.com/package/ng-click-outside
中看到它此致
只需使用 (click) 事件绑定,从组件的实例传递一个函数就可以了。
解法: 声明指令 ClickOutside 如下所示:
@Directive({
selector: '[clickOutside]',
})
export class ClickOutsideDirective {
@Output('onClickOutside') onClickOutside = new EventEmitter<MouseEvent>();
constructor(private _eref: ElementRef) {}
@HostListener('document:click', ['$event', '$event.target'])
onDocumentClicked(event: MouseEvent, targetElement: HTMLElement) {
if (targetElement && document.body.contains(targetElement) && !this._eref.nativeElement.contains(targetElement)) {
this.onClickOutside.emit(event);
}
}
}
}
<div clickOutside (onClickOutside)="onClickOutside()">
...
</div>
并且在名为 ng-click-outside.
的 npm 模块中有一个指令安装:npm install --save ng-click-outside
阅读下面 link 中的完整文档: