如何防止角材料垫菜单关闭?
Posted
技术标签:
【中文标题】如何防止角材料垫菜单关闭?【英文标题】:How to prevent angular material mat-menu from closing? 【发布时间】:2018-04-08 15:24:15 【问题描述】:我正在角度材料中创建一个日期时间选择器控件,并使用以下代码来执行此操作
<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>
目前,当我单击一个按钮时,它会关闭菜单。我知道我们可以对每个 mat-menu-item 执行 $event.stoppropagation() 以防止它关闭。
但我想知道 mat-calendar 是否可以这样做
正如您在上图中看到的,当前当我选择一个日期时,它正在关闭菜单。有没有可能防止这种情况发生?
【问题讨论】:
您好,您成功制作了这样的日期范围选择器吗?我需要一个,但并没有心情重新发明***。 【参考方案1】:您只需将(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>
Stackblitz demo.
【讨论】:
似乎效果不佳。单击日期时无法选择日期 它非常适合单个 div,但我想对整个 mat-menu 做同样的事情,这样无论用户在 mat-menu 内单击什么位置,它都不应该关闭,不幸的是$event.stoppropagation()
不起作用整个菜单
为我工作。我在 mat-menu 中添加了一个包装器 div,并在其上添加了 $event.stoppropagation()
。
mat-menu 中的复选框对我有用,非常感谢
此解决方案的另一个问题是,当您单击父元素上的某个位置时,不会触发来自内部所有元素的 blur
之类的事件。这导致我mat-autocomplete
在父元素上单击其他位置时不会关闭,所以我必须找到另一个解决方案【参考方案2】:
通过返回上一个解决方案,将指令封装在一个方法中允许不关闭菜单并继续执行指令
在 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>
在 TS:
doSomething($event:any)
$event.stopPropagation();
//Another instructions
【讨论】:
【参考方案3】:如果您想在单击 mat-menu-content 时停止关闭 mat-menu,我确实在锚标记而不是 mat-menu 上添加了 $event.stopPropogation()
。
因此,即使单击表单上的任何位置,菜单对话框也不会关闭。
Example:-
<mat-menu #nameAndDescriptioContextMenu="matMenu" [hasBackdrop]="false">
<a (click)="$event.stopPropagation();$event.preventDefault();">
<div>
Form Group Form
</div>
</a>
</mat-menu>
【讨论】:
爱它,兄弟。干得好!【参考方案4】:你有很多选择,我邀请你尝试以下
<mat-menu [hasBackdrop]="false">
<div (click)="$event.stopPropagation()" (keydown)="$event.stopPropagation()">
...
</div>
</mat-menu>
[hasBackdrop]="false" 如果您想防止在单击框外任意位置时关闭 mat-menu,否则将其删除
【讨论】:
【参考方案5】:不幸的是,以上答案都不适合我。如果您需要菜单面板比内容宽得多,则没有可以放置"$event.stopPropagation();"
的位置,因此如果您单击 mat-menu-panel 它将关闭。
幸运的是,仍然有一种方法可以避免这种情况,通过“覆盖”click
MatMenu 事件。
这里是 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(),
);
这样,只有在您单击外部(这很容易删除)并且使用触发器时,它才会关闭。 这是我在项目中想要的行为,我希望它对某人有用。
【讨论】:
【参考方案6】:你可以直接在你的组件中使用这个指令。
在 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>
将其保存为 filter.directive.ts 从“@angular/core”导入指令、HostListener、HostBinding;
@Directive(
selector: "[mat-filter-item]"
)
export class FilterItemDirective
@HostListener("click", ["$event"])
onClick(e: MouseEvent)
e.stopPropagation();
e.preventDefault();
return false;
【讨论】:
以上是关于如何防止角材料垫菜单关闭?的主要内容,如果未能解决你的问题,请参考以下文章