如何让Angular 8中cdkDrag与mat-grid-list拖拽后保持网格布局?
解决Angular Material mat-grid-list结合cdkDrag后网格布局混乱的问题
我来帮你搞定这个问题!你当前的代码之所以拖拽后无法保持整齐的网格布局,核心原因是DOM结构不符合mat-grid-list的组件规范——mat-grid-list要求直接子元素必须是mat-grid-tile,但你现在用一个带cdkDrag的div包裹了mat-grid-tile,这破坏了mat-grid-list的布局逻辑,导致它无法正确识别并排列tile。
解决方案:调整结构,让cdkDrag直接作用于mat-grid-tile
我们需要修改DOM结构,让mat-grid-list直接作为拖拽容器(cdkDropList),同时把cdkDrag指令直接绑定到mat-grid-tile上,这样既能保留拖拽功能,又能让mat-grid-list维持正常的网格布局。
修改后的完整代码:
app.component.html
<style> .mat-grid-tile { position: relative; /* 确保拖拽手柄的绝对定位相对于tile本身 */ } .drag-handle { position: absolute; top: 10px; left: 10px; color: #ccc; cursor: move; width: 24px; height: 24px; z-index: 10; /* 保证拖拽手柄在tile内容上方 */ } </style> <div cdkScrollable> <mat-grid-list cols="4" rowHeight="3:4" style="width: 25%;" cdkDropList (cdkDropListDropped)="drop($event)" > <mat-grid-tile *ngFor="let number of numbers" style="border: 1px solid green;" cdkDrag > {{number}} <div class="drag-handle" cdkDragHandle> <svg width="24px" fill="currentColor" viewBox="0 0 24 24"> <path d="M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z"></path> <path d="M0 0h24v24H0z" fill="none"></path> </svg> </div> </mat-grid-tile> </mat-grid-list> </div>
app.component.ts(无需修改,保持原有逻辑即可)
import { Component } from '@angular/core'; import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'drag-drop'; numbers: number[] = []; constructor() { for (let i = 0; i < 100; i++) { this.numbers.push(i); } } drop(event: CdkDragDrop<number[]>) { moveItemInArray(this.numbers, event.previousIndex, event.currentIndex); } }
关键修改说明:
- 修复DOM结构:将
cdkDropList和拖拽触发事件绑定到mat-grid-list本身,同时移除包裹mat-grid-tile的额外div,直接在mat-grid-tile上使用cdkDrag。这样mat-grid-list的直接子元素都是符合要求的mat-grid-tile,能正常按网格规则排列。 - 调整样式:给
mat-grid-tile添加position: relative,确保拖拽手柄的绝对定位是相对于tile本身,而不是其他父元素。 - 保留拖拽逻辑:原有的
drop函数无需改动,因为我们依然是通过修改numbers数组的顺序来控制tile的排列,mat-grid-list会根据数组的新顺序自动重新渲染,保持整齐的4列网格布局。
这样修改后,你拖拽tile时,mat-grid-list会始终按照数组顺序维护网格结构,拖拽完成后tile会自动归位到网格的对应位置,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Jørgen Rasmussen
相关产品推荐
相关产品推荐

