使用CDK拖放时更改角度Mat-List-Option布局

时间:2019-10-07 21:30:48

标签: angular-material

我正在开发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}}。

有人知道为什么拖动时布局会发生变化吗?

3 个答案:

答案 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>

重要提示:ma​​tchSize 输入是自动调整拖动项目大小所必需的。

并且由于 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;
}

拖动时看起来像这样:

enter image description here