我正在开发Angular 7 Web应用程序,并且在Mat-Selection-List
中苦苦挣扎,在这里我允许用户拖放mat-list-option
项目。
每个mat-list-option
项目都包含一个div
,该项目使用Flex布局按如下方式排列其组件:
<mat-selection-list #taskGroupSelectionList
cdkDropList
[(ngModel)]="selectedOptions"
(ngModelChange)="onNgModelChange($event)"
(selectionChange)="onSelectionChange($event)"
class="task-group-list"
(cdkDropListDropped)="drop($event)">
<mat-list-option class="task-group-box" checkboxPosition="after" *ngFor="let taskGroup of taskGroups" [value]="taskGroup" cdkDrag>
<!-- Task Group Item -->
<div fxLayout="row" *ngIf="taskGroup" fxLayoutAlign="start center" style="width: 100%; height: 100%;">
<!-- Move Handle -->
<div fxFlex="32px" style="padding: 0 0 0 4px;">
<mat-icon class="summary-channel-handle">menu</mat-icon>
</div>
<!-- Index -->
<div fxFlex="24px;">
<p style="margin: 0; text-align: right;">
{{taskGroup.orderId}}:
</p>
</div>
<!-- Title -->
<div fxFlex="nogrow">
<p style="margin: 0; padding: 0 0 0 8px; text-overflow: ellipsis; white-space: nowrap;">
{{taskGroup.title}}
</p>
</div>
</div>
</mat-list-option>
</mat-selection-list>
此简单组件的主要CSS样式如下:
.task-group-list {
width: 100%;
height: 100%;
display: block;
background: white;
}
.task-group-box {
border-left: solid 1px #ddd;
border-right: solid 1px #ddd;
border-bottom: solid 1px #ddd;
border-radius: 4px;
height: 48px;
color: rgba(0, 0, 0, 0.87);
box-sizing: border-box;
cursor: move;
background: white;
}
.task-group-box:first-child {
border: solid 1px #ddd;
}
.task-group-list.cdk-drop-list-dragging .task-group-box:not(.cdk-drag-placeholder) {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
.cdk-drag-preview {
box-sizing: border-box;
border-radius: 4px;
height: 48px;
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
}
.cdk-drag-placeholder {
box-sizing: border-box;
border-radius: 4px;
height: 48px;
opacity: 0;
}
.cdk-drag-animating {
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
}
从功能上讲,我可以拖放列表项,但是在拖动时,我放在右侧mat-list-option
的{{1}}复选框将移至左上角并推动{{ 1}}。
有人知道为什么拖动时布局会发生变化吗?
答案 0 :(得分:0)
被拖动的元素可以作为DOM中的最后一个子元素(仅在拖动时),这会产生很多问题,您可以阅读here。
如果您的mat-list-option元素不是很复杂,只需复选框和一些文本,则可以通过向全局styles.css文件中添加一些CSS来解决此问题,例如:
/* Checkbox and text inline and vertically centered */
.cdk-drag-preview .mat-list-item-content {
display: flex;
align-items: center;
}
/* Checkbox margin from text */
.cdk-drag-preview .mat-pseudo-checkbox {
margin-right: 10px;
}
您可以在我创建的堆叠闪电战中看到DEMO。
如果您的mat-list-option元素的内容有点复杂,则需要检查该元素并添加必要的样式。您可以通过拖动mat-list-option并在拖动时单击鼠标右键,检查元素并查找可用于为其设置样式的类来实现此目的。
答案 1 :(得分:0)
尝试:: ng-deep
bottom: 0
这对我有用
答案 2 :(得分:0)
更好的替代方法可能是创建一个 custom cdkDragPreview。您可以随意设置样式。
<mat-selection-list #movies cdkDropList>
<mat-list-option *ngFor="let movie of movies" cdkDrag>
{{movie}}
<ng-template cdkDragPreview [matchSize]="true">
<div class="movie-preview">
{{ movie }}
</div>
</ng-template>
</mat-list-option>
</mat-selection-list>
重要提示:matchSize 输入是自动调整拖动项目大小所必需的。
并且由于 css 的作用域是您的组件,即使它移到组件的 DOM 树之外,它也会保留样式(假设是模拟样式封装)。
.movie-preview
{
line-height: 3;
padding: 0 1em;
color: hotpink;
background: white;
/* border (and hotpink color) are optional, based on your preference */
border: 1px solid #ccc;
border-radius: .5em;
}
拖动时看起来像这样: