我有一个多组件侧边栏开关,app / button / sidebar都在其自己的组件中,button / sidebar是应用的子级(或至少加载在应用程序组件中,假设这是子级)
在Angular的跨组件通信方面还不够快,在这种情况下,我正在使用服务。
我要做什么:如果未单击组件 button 或侧边栏(这两个组件之外的任何内容)...,则折叠侧边栏。
目前,我正在服务中的“可见”变量上切换布尔状态以扩展/折叠导航。
我尝试了所有方法,但收效甚微。有什么方法可以做到这一点?或者至少在我能读到的地方可以靠近并从那里拿走它?
代码:https://stackblitz.com/edit/multi-component-communication
答案 0 :(得分:1)
如果document:click
事件处理程序切换了visible
标志,则当前代码有效:
@HostListener("document:click", ["$event"])
onClick(event) {
this.visible = this._ref.nativeElement.contains(event.target);
}
为防止按钮单击到达文档级别,请停止事件传播:
<toggle-sidebar (click)="$event.stopPropagation()"></toggle-sidebar>
有关演示,请参见this stackblitz。
答案 1 :(得分:1)
您可以在侧边栏和按钮中处理clickOutSide
。如果两者都在外部单击,请关闭侧边栏。您可以通过@ Output / EventEmitter在两个子组件中实现相同的目的,并在app.component.ts
文件中收听它们。
所以,总结一下:
clickOutSide
,然后将其发送给父级,即app.component.ts
clickOutSide
,然后将其发送给父级,即app.component.ts
app.component.ts
中,上面的handle发出并执行检查:
考虑到上述情况,我已经编辑了您的堆叠here。
答案 2 :(得分:0)
您应该使用指令来收听外部面板的点击:
import { Directive, ElementRef, EventEmitter, HostListener, Output } from '@angular/core';
@Directive({
selector: '[clickOutside]'
})
export class ClickOutsideDirective {
@Output() clickOutside: EventEmitter<Event> = new EventEmitter<Event>();
constructor(private elementRef: ElementRef) { }
@HostListener('document:mousedown', ['$event'])
onDocumentClick(event: Event) {
if (!this.isClickInElement(event)) {
this.clickOutside.emit(event);
}
}
private isClickInElement(event: Event): boolean {
return this.elementRef.nativeElement.contains(event.target);
}
}
现在您可以在菜单上附加此指令并绑定到其输出,然后调用该方法折叠边栏或执行操作。例如:
<ol (clickOutside)="collapseSideBar()">