Javascript 如何防止角材料垫菜单关闭?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46967970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to prevent angular material mat-menu from closing?
提问by Umamaheswaran
I'm creating a date time picker control in the angular material and having the below code to do that
我正在角度材料中创建一个日期时间选择器控件并使用以下代码来执行此操作
<button mat-button [matMenuTriggerFor]="menu">
<mat-icon>date_range</mat-icon>
<span>Date Range</span>
</button>
<mat-menu #menu="matMenu">
<div fxLayout="row">
<div fxLayout="column">
<button (click)="setInterval(15)" mat-menu-item>Last 15 minutes</button>
<button (click)="setInterval(360)" mat-menu-item>Last 6 hours</button>
<button (click)="setInterval(1440)" mat-menu-item>Last 24 hours</button>
<button (click)="setInterval(2880)" mat-menu-item>Last 2 days</button>
<button (click)="setInterval(10080)" mat-menu-item>Last 7 days</button>
<button (click)="setInterval(-1)" [matMenuTriggerFor]="dateTimeMenu" mat-menu-item>Custom</button>
</div>
<mat-menu class="date-range-menu" #dateTimeMenu="matMenu">
<div fxLayout="row">
<div fxLayout="column">
<b>From</b>
<mat-calendar></mat-calendar>
</div>
<div fxLayout="column">
<b>To</b>
<mat-calendar></mat-calendar>
</div>
</div>
</mat-menu>
</div>
</mat-menu>
Currently when ever I click a button it is closing the menu. I know we can do $event.stoppropagation() on each mat-menu-item to prevent it from closing.
目前,当我点击一个按钮时,它正在关闭菜单。我知道我们可以在每个 mat-menu-item 上执行 $event.stoppropagation() 以防止它关闭。
But I want to know is it possible to do that for mat-calendar
但我想知道是否可以为 mat-calendar 做到这一点
As you can see in the above image currently when i select a date it is closing the menu. Is it possible to prevent that?
正如您在上图中所看到的,当我选择一个日期时,它正在关闭菜单。有可能阻止吗?
回答by Anik
You just add (click) = "$event.stopPropagation()"to the parent element of these calendars. Like below,
您只需添加(click) = "$event.stopPropagation()"到这些日历的父元素即可。像下面,
<mat-menu class="date-range-menu" #dateTimeMenu="matMenu">
<div fxLayout="row">
<div fxLayout="column" (click)="$event.stopPropagation();">
<b>From</b>
<mat-calendar></mat-calendar>
</div>
<div fxLayout="column" (click)="$event.stopPropagation();">
<b>To</b>
<mat-calendar></mat-calendar>
</div>
</div>
</mat-menu>
回答by JLazar0
By giving a return to the previous solution, encapsulating the instruction in a method allows not to close the menu and continue executing instructions
通过返回之前的解决方案,将指令封装在方法中允许不关闭菜单并继续执行指令
IN HTML:
在 HTML 中:
<mat-menu class="date-range-menu" #dateTimeMenu="matMenu">
<div fxLayout="row">
<div fxLayout="column" (click)="doSomething($event);">
<b>From</b>
<mat-calendar></mat-calendar>
</div>
<div fxLayout="column" (click)="doSomething($event)">
<b>To</b>
<mat-calendar></mat-calendar>
</div>
</div>
</mat-menu>
IN TS:
在 TS:
doSomething($event:any){
$event.stopPropagation();
//Another instructions
}
回答by gaurav sharma
you can use this directive directly in your component.
你可以直接在你的组件中使用这个指令。
in HTML
在 HTML 中
<mat-menu class="date-range-menu" #dateTimeMenu="matMenu">
<div fxLayout="row">
<div fxLayout="column" mat-filter-item>
<b>From</b>
<mat-calendar></mat-calendar>
</div>
<div fxLayout="column" mat-filter-item >
<b>To</b>
<mat-calendar></mat-calendar>
</div>
</div>
</mat-menu>
save it as filter.directive.ts import { Directive, HostListener, HostBinding } from "@angular/core";
将其另存为 filter.directive.ts import { Directive, HostListener, HostBinding } from "@angular/core";
@Directive({
selector: "[mat-filter-item]"
})
export class FilterItemDirective {
@HostListener("click", ["$event"])
onClick(e: MouseEvent) {
e.stopPropagation();
e.preventDefault();
return false;
}
}
回答by Amarula
Unfortunately, none of the above answers worked for me. In cases when you need menu panel to be much wider than the content, there is no place you can put "$event.stopPropagation();"on, so if you click on mat-menu-panel it will close.
Luckily, there is still a way to avoid this, by 'overriding' clickevent of MatMenu.
Here is stackblitz example, thanks to my colleague: https://stackblitz.com/edit/mat-menu-disable-close
不幸的是,上述答案都不适合我。如果您需要菜单面板比内容宽得多,则没有地方可以放置"$event.stopPropagation();",因此如果您单击 mat-menu-panel 它将关闭。幸运的是,仍然有一种方法可以通过“覆盖” clickMatMenu 事件来避免这种情况。这是stackblitz的例子,感谢我的同事:https://stackblitz.com/edit/mat-menu-disable-close
ngAfterViewInit() {
// Inject our custom logic of menu close
(this.searchMenu as any).closed = this.searchMenu.close = this.configureMenuClose(this.searchMenu.close);
}
private configureMenuClose(old: MatMenu['close']): MatMenu['close'] {
const upd = new EventEmitter();
feed(upd.pipe(
filter(event => {
if (event === 'click') {
// Ignore clicks inside the menu
return false;
}
return true;
}),
), old);
return upd;
}
}
function feed<T>(from: Observable<T>, to: Subject<T>): Subscription {
return from.subscribe(
data => to.next(data),
err => to.error(err),
() => to.complete(),
);
}
This way, it will close only if you click outside (that's an easy to remove) and if you use trigger. That is the behavior I wanted in my project and I hope it will be useful for someone.
这样,只有当您单击外部(这很容易删除)并且您使用触发器时,它才会关闭。这就是我在我的项目中想要的行为,我希望它对某人有用。


