角度:v8.2.8
私はMAT-MENU(Angular素材)を使用してコンテキストメニューをエミュレートすることを管理します。私のページ上での右クリックすると、メニューがマウスの場所に表示されます。
私が達成したいもの:マウスをページ上の別の場所に移動すると、もう一度右クリックします。元の場所のメニューが新しい場所で閉じて再び開くことを期待していました。
しかし実際には右クリックすると、何も起こらず、元の場所のメニューは開いたままです。
実際、私は最初にクリックしてオープンのメニューを元の場所に閉じてください。その後に新しいマウスの場所でメニューを開くために右クリックします。
質問:私が欲しいものを達成する方法は何ですか?
@Component({
selector: 'fl-home',
template:`
<mat-menu #contextmenu>
<div >
<button mat-menu-item>Clear all Paths</button>
</div>
</mat-menu>
<div [matMenuTriggerFor]="contextmenu" [style.position]="'absolute'" [style.left.px]="menuX" [style.top.px]="menuY" ></div>
<div class="container" (contextmenu)="onTriggerContextMenu($event);"> ....</div>
`})
export class HomeComponent {
menuX:number=0
menuY:number=0
@ViewChild(MatMenuTrigger,{static:false}) menu: MatMenuTrigger;
onTriggerContextMenu(event){
event.preventDefault();
this.menuX = event.x - 10;
this.menuY = event.y - 10;
this.menu.closeMenu() // close existing menu first.
this.menu.openMenu()
}
}
_
私の解決策
ngOnInit(): void {
this.windowClickSubscription = fromEvent(window, 'click').subscribe((_) => {
if (this.contextMenu.menuOpen) {
this.contextMenu.closeMenu();
}
});
}
ngOnDestroy(): void {
this.windowClickSubscription && this.windowClickSubscription.unsubscribe();
this.menuSubscription && this.menuSubscription.unsubscribe();
}
onContextMenu(event: MouseEvent){
event.preventDefault();
this.menuSubscription && this.menuSubscription.unsubscribe();
this.menuSubscription = of(1)
.pipe(
tap(() => {
if (this.contextMenu.menuOpen) {
this.contextMenu.closeMenu();
}
this.contextMenuPosition.x = event.clientX;
this.contextMenuPosition.y = event.clientY;
}),
// delay(this.contextMenu.menuOpen ? 200 : 0),
delayWhen((_) => (this.contextMenu.menuOpen ? interval(200) : of(undefined))),
tap(async() => {
this.contextMenu.openMenu();
let backdrop: HTMLElement = null;
do {
await this.delay(100);
backdrop = document.querySelector(
'div.cdk-overlay-backdrop.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing'
) as HTMLElement;
} while (backdrop === null);
backdrop.style.pointerEvents = 'none';
})
)
.subscribe();
}
delay(delayInms: number) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(2);
}, delayInms);
});
}
_
多分あなたはそれを解決しました、しかし、ここに私のこの問題への私のアプローチです:divのサラウンドメニュー項目、そしてマウスの葉のメニュー(そのdiv)がそれを閉じるので、もう一度それを再度右折することができます。 ....
<div (mouseleave)="mouseLeaveMenu()">
...menu items...
</div>
...
mouseLeaveMenu() {
if (this.contextMenu.menuOpened) this.contextMenu.closeMenu();
}
_