我正在使用 cdk-virtual-scroll-viewport 显示大量元素列表,如下所示
<cdk-virtual-scroll-viewport itemSize="115px" class="scrollable-card">
<div *cdkVirtualFor="let project projects">
<app-project-card [project]="project"></app-project-card>
</div>
</cdk-virtual-scroll-viewport>
我在 app-project-card 组件中定义了一个上下文菜单,如下所示
<mat-card class='project-card' (contextmenu)="onRightClick($event)">
//other elements inside which are irrelavant
</mat-card>
<div style="visibility: hidden; position: fixed;" [style.left]="menuTopLeftPosition.x"
[style.top]="menuTopLeftPosition.y" [matMenuTriggerFor]="menu"></div>
<mat-menu #menu="matMenu">
<button mat-menu-item (click)="onEdit(project.id)"><mat-icon>edit</mat-icon>Edit</button>
<button mat-menu-item (click)="onDelete(project.id)"><mat-icon>delete_outline</mat-icon>Delete</button>
</mat-menu>
下面是我的 onRightClick 函数的代码。
onRightClick(event: MouseEvent) {
event.preventDefault(); // Prevent the browser's default context menu
// Set the position of the context menu
this.menuTopLeftPosition.x = `${event.clientX}px`;
this.menuTopLeftPosition.y = `${event.clientY}px`;
// Open the context menu
this.matMenuTrigger.openMenu();
}
我面临的问题是我的上下文菜单没有显示在正确的坐标上。坐标似乎是相对于视口计算的,我不确定。
滚动视口会更改 y 坐标偏离的值。 x 坐标保持不变但已关闭。如果您需要更多背景信息,请告诉我。谢谢你
我觉得你的.html可以是这样的
<mat-card class="project-card">
<mat-card-content>
{{data()?.name}} {{data()?.id}}
<div
#menuTrigger="cdkContextMenuTriggerFor"
class="fill example-standalone-trigger"
(mouseup)="open(menuTrigger)"
[cdkContextMenuTriggerFor]="menu"
></div>
</mat-card-content>
</mat-card>
<ng-template #menu>
<div class="example-menu" cdkMenu (closed)="open(null)">
<button class="example-menu-item" cdkMenuItem>Refresh</button>
<button class="example-menu-item" cdkMenuItem>Settings</button>
<button class="example-menu-item" cdkMenuItem>Help</button>
<button class="example-menu-item" cdkMenuItem>Sign out</button>
</div>
</ng-template>
哪里
.fill{
position:absolute;
top:0;
bottom:0;
width:100%;
}
.mat-mdc-card{
position:relative;
}
还有
export class CardComponent {
data = input<{ id: number; name: string }>();
menuOpened = output<CdkContextMenuTrigger | null>();
open(menu: any) {
if (menu)
setTimeout(() => {
this.menuOpened.emit(menu);
});
else this.menuOpened.emit(null);
}
}
我制作了当菜单打开/关闭时发出触发器以允许在滚动时关闭(我真的很疯狂,因为对我(打开)和(关闭)事件不起作用。
“父母”喜欢
<cdk-virtual-scroll-viewport itemSize="50" class="example-viewport" #scroller>
<div *cdkVirtualFor="let item of items" class="example-item">
<app-card [data]="item" (menuOpened)="trigger=$event" />
</div>
</cdk-virtual-scroll-viewport>
还有
trigger!: CdkContextMenuTrigger | null;
@ViewChild('scroller', { static: true }) scroller!: CdkVirtualScrollViewport;
items: any[] = Array(100)
.fill('')
.map((x, index) => {
return { id: index, name: 'name ' + index };
});
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.scroller
.elementScrolled()
.pipe(filter((_: any) => this.trigger != null))
.subscribe((_) => {
this.ngZone.run(() => {
this.trigger?.close();
});
});
}