【问题标题】:Angular. Drag & drop in flex list角。在弹性列表中拖放
【发布时间】:2019-04-22 16:02:03
【问题描述】:

我需要在列表中拖放 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;
}

【问题讨论】:

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


    【解决方案1】:

    这是 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-orientation-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++])
        );
      }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-22
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多