有角度的。拖放弹性列表

时间:2019-04-22 16:02:04

标签: html css angular typescript drag-and-drop

我需要在列表中拖放div。但是div动作异常。对象没有移动到我需要的地方。

请帮助我

TS:

timePeriods = [
    '1', '2', '3', '4', '5', '6', '7'
  ];

  drop(event: CdkDragDrop<string[]>) {
    moveItemInArray(this.timePeriods, event.previousIndex, event.currentIndex);
  }

HTML:

<div cdkDropList cdkDropListOrientation="horizontal" class="list" (cdkDropListDropped)="drop($event)">
<div class="box" *ngFor="let timePeriod of timePeriods" cdkDrag>{{timePeriod}}</div>

CSS:

.box {
  width: 33%;
  border: solid 1px #ccc;
  margin: 3em;
}

.list {
  width: 100%;
  border: solid 1px #ccc;
  height: 90%;
  display: flex;
  flex-direction: row;
  background: white;
  border-radius: 4px;
  overflow: hidden;
  justify-content: space-around;
  flex-wrap: wrap;
}

enter image description here

1 个答案:

答案 0 :(得分:0)

这是Angular CDK drag and drop issue inside CSS flexbox的副本。

在这里,我建议创建一个代表您的弹性列表的项目表矩阵。我在这里发布了详细的解释:https://taitruong.github.io/software-developer.org/post/2019/10/26/Angular-drag'n'drop-mixed-ientation-in-flex-row-wrap /

我在这里为您的问题在StackBlitz上实现了一个解决方案:https://stackblitz.com/edit/angular-drag-and-drop-in-flex-list

模板:

<div #rowLayout cdkDropListGroup>
  <!-- based on row layout's width and item box width, columns per row can be calculated and a items table matrix is initialized-->
  <div
    *ngFor="let itemsRow of getItemsTable(rowLayout)"
    cdkDropList
    class="list"
    cdkDropListOrientation="horizontal"
    [cdkDropListData]="itemsRow"
    (cdkDropListDropped)="reorderDroppedItem($event)"
  >
    <!-- drop reorders items and recalculates table matrix-->
    <div class="box" *ngFor="let item of itemsRow" cdkDrag>
      <div class="drag-placeholder" *cdkDragPlaceholder></div>
      {{ item }}
    </div>
  </div>
</div>

CSS:

.box {
    width: 33%;
    border: solid 1px #ccc;
    margin: 1em;
  }

  .list {
    width: 100%;
    border: solid 1px #ccc;
    height: 90%;
    display: flex;
    flex-direction: row;
    background: white;
    border-radius: 4px;
    overflow: hidden;
    justify-content: space-around;
    flex-wrap: wrap;
  }

  .drag-placeholder {
    background: #ccc;
    width: 3em;
    border: dotted 3px #999;
    transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
  }

组件:

export class AppComponent {

  timePeriods = ["1", "2", "3", "4", "5", "6", "7"];
  itemsTable: Array<string[]>;

  getItemsTable(rowLayout: Element): string[][] {
    if (this.itemsTable) {
      return this.itemsTable;
    }
    // calculate column size per row
    const { width } = rowLayout.getBoundingClientRect();
    const boxWidth = Math.round(width * .33); // 33% as defined in css
    const columnSize = Math.round(width / boxWidth);

    // calculate row size: items length / column size
    // add 0.5: round up so that last element is shown in next row
    const rowSize = Math.round(this.timePeriods.length / columnSize + .5);

    // create table rows
    const copy = [...this.timePeriods];
    this.itemsTable = Array(rowSize)
      .fill("")
      .map(
        _ =>
          Array(columnSize) // always fills to end of column size, therefore...
            .fill("")
            .map(_ => copy.shift())
            .filter(item => !!item) // ... we need to remove empty items
      );
    return this.itemsTable;
  }

  reorderDroppedItem(event: CdkDragDrop<number[]>) {
    // clone table, since it needs to be re-initialized after dropping
    let copyTableRows = this.itemsTable.map(_ => _.map(_ => _));

    // drop item
    if (event.previousContainer === event.container) {
      moveItemInArray(
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    } else {
      transferArrayItem(
        event.previousContainer.data,
        event.container.data,
        event.previousIndex,
        event.currentIndex
      );
    }

    // update items after drop
    this.timePeriods = this.itemsTable.reduce((previous, current) =>
      previous.concat(current)
    );

    // re-initialize table
    let index = 0;
    this.itemsTable = copyTableRows.map(row =>
      row.map(_ => this.timePeriods[index++])
    );
  }

}