簡體   English   中英

如何防止角材料墊菜單關閉?

[英]How to prevent angular material mat-menu from closing?

我正在角度材料中創建一個日期時間選擇器控件並使用以下代碼來執行此操作

<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 做到這一點

在此處輸入圖片說明

正如您在上圖中所看到的,當我選擇一個日期時,它正在關閉菜單。 有可能阻止嗎?

您只需將(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 演示

通過返回之前的解決方案,將指令封裝在方法中允許不關閉菜單並繼續執行指令

在 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
}

如果您想停止關閉 mat-menu,即使單擊 mat-menu-content 我確實在錨標簽上添加了$event.stopPropogation()而不是 mat-menu。 因此,即使單擊表單上的任何位置,菜單 dailog 也不會關閉。

Example:- 
    <mat-menu #nameAndDescriptioContextMenu="matMenu" [hasBackdrop]="false">
         <a (click)="$event.stopPropagation();$event.preventDefault();">
               <div>
                 Form Group Form
               </div> 
         </a> 
    </mat-menu>

你有很多選擇,我邀請你嘗試以下

    <mat-menu [hasBackdrop]="false">
     <div  (click)="$event.stopPropagation()" (keydown)="$event.stopPropagation()">
     ...
     </div>
    </mat-menu>

[hasBackdrop]="false"如果你想在點擊框外的任何地方時阻止關閉 mat-menu,否則將其刪除

不幸的是,上述答案都不適合我。 如果您需要菜單面板比內容寬得多,則沒有地方可以放置"$event.stopPropagation();" 上,因此如果您單擊 mat-menu-panel,它將關閉。 幸運的是,仍然有一種方法可以避免這種情況,通過“覆蓋” MatMenu 的click事件。 這是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(), ); }

這樣,只有當您單擊外部(這很容易刪除)並且您使用觸發器時,它才會關閉。 這就是我在我的項目中想要的行為,我希望它對某人有用。

你可以直接在你的組件中使用這個指令。

在 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 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;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM